首先Mysql的基本存储结构是页(记录都存在页里边):
所以说,如果我们写select * from user where username = 'Java3y'这样没有进行任何优化的sql语句,默认会这样做:
很明显,在数据量很大的情况下这样查找会很慢!
1.2索引提高检索速度
索引做了些什么可以让我们查询加快速度呢?
其实就是将无序的数据变成有序(相对):
要找到id为8的记录简要步骤:
很明显的是:没有用索引我们是需要遍历双向链表来定位对应的页,现在通过**“目录”**就可以很快地定位到对应的页上了!
其实底层结构就是B+树,B+树作为树的一种实现,能够让我们很快地查找出对应的记录。
参考资料:
1.3索引降低增删改的速度
B+树是平衡树的一种。
平衡树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
如果一棵普通的树在极端的情况下,是能退化成链表的(树的优点就不复存在了)
B+树是平衡树的一种,是不会退化成链表的,树的高度都是相对比较低的(基本符合矮矮胖胖(均衡)的结构)【这样一来我们检索的时间复杂度就是O(logn)】!从上一节的图我们也可以看见,建立索引实际上就是建立一颗B+树。
B+树删除和修改具体可参考:
1.4哈希索引
除了B+树之外,还有一种常见的是哈希索引。
哈希索引采用的结构和hashMap一样。数组+链表的形式。如果hash冲突大,性能也就越来越差。
看起来哈希索引很牛逼啊,但其实哈希索引有好几个局限(根据他本质的原理可得):
1.5InnoDB支持哈希索引吗?
主流的还是使用B+树索引比较多,对于哈希索引,InnoDB引擎会根据索引值使用的频繁内部自动的在B+Tree索引上创建哈希索引,用户无法控制或者配置,不过可以关闭该优化特性。
1.6聚集和非聚集索引
简单概括:
区别:
非聚集索引也叫做二级索引
非聚集索引在建立的时候也未必是单列的,可以多个列来创建索引。
在创建多列索引中也涉及到了一种特殊的索引-->覆盖索引
比如说:
1.7索引最左匹配原则
最左匹配原则:
例子:
1.8=、in自动优化顺序
不需要考虑=、in等的顺序,mysql会自动优化这些条件的顺序,以匹配尽可能多的索引列。
例子:
1.9索引总结
索引在数据库中是一个非常重要的知识点!上面谈的其实就是索引最基本的东西,要创建出好的索引要顾及到很多的方面:
根据上面这些原则,我们来修改开篇的慢查询:
SELECT
count(*) AS count
FROM trade_bASe AS a
WHERE
a.trade_status = 7
AND a.create_time > '2015-09-01'
AND a.booking_source = '2'
根据这条SQL,应该建立的索引是:trade_status, booking_source,create_time的联合索引;其中,trade_status、booking_source的顺序可以颠倒,而且 create_time 的区间查询放到后面。这就是利用了索引的最左匹配原则。
索引的优化方法
1,尽量使用组合索引,因为即使查询语句中有多个单列索引,但是优化器会只选择一个它认为最优的索引路径查询。
2,索引不会包含有NULL值的列:只要列中包含有NULL值,都将不会被包含在索引中,组合索引中只要有一列有NULL值,那么这一列对于此条组合索引就是无效的。所以我们在数据库设计时,不要让索引字段的默认值为NULL。
3,对于指比较长的列可以创建前缀索引,但是前缀索引无序无法用做orderby 和groupby和覆盖扫描。:假设,如果有一个数据类型为CHAR(255)的city列,在前10个字符内,绝大部分数据的值是唯一的,那么就不要对整个列进行索引,创建alter table t_demo add key(city(10));字段长度为10的city索引。
4,对于指比较长的列如url还可以使用伪哈希索引的方式。增加一列url对应的hash整型值。维护该列可以使用触发器实现。注意:因为会出现hash冲突,所以根据整型hash列查询的时候都要and 具体值。如:select id from urlTable where url_crc=CRC32(“www.baidu.com”) and url="www.baidu.com"
5,LIKE语句操作:LIKE "%aaaaa%"不会使用索引,但是LIKE "aaa%"可以使用索引。结合B+树查找规则理解
6,不要在索引列上进行运算:在建立索引的原则中,提到了索引列不能进行运算。
7,使用覆盖索引,索引包含需要查询的字段的值。
8,尽可能将需要做范围(>,<)查询的列放在索引后面,因为优化器会放弃使用索引。注意:in 和 between 是可以使用索引的,它们相当于等值查询。
最优的索引符合三星系统原则
1.索引将相关记录放在一起获得一星
2.索引中数据顺序和查询中的排序一致则获得二星
3.覆盖索引获得三星
Explain命令
explain select * from t_user;
列值的含义
possable_key:可能会用到的索引。
key:表示使用到的索引