MySQL index entry refers to the North

Since two years ago, learned of the index, I always wanted to write an article about the index. But I am a delay in cancer patients, dragged on for two years, is indeed me. The article considered his notes, welcome criticism.

Outline

What indexes are? Many books and articles will use the book catalog analogy. The purpose is to use the directory to help us find the location of specific content, scope specific chapters. Similarly, MySQL uses the index is to help us speed up queries and sorting.

Index type are in InnoDB hash index, B + tree index, full-text indexing. Adaptive hash index is designed in InnoDB, do not discuss. After InnoDB1.12 have a full-text index is inverted applications, have not stepped pit (reportedly does not support Chinese), we have time to look.

Data in this chapter discuss the B + tree index.

B + tree
learning MySQL index, have to first understand its principles, otherwise a lot of problems will be confused. The following describes the principle of the index data structure, without involving the complexity of the implementation.

Before turning to B + tree, you may wish to ponder why the index can speed up queries? Why use B + tree as the index instead of a B-tree? Hash index query complexity is O (1) Why is it does not have a hash index?

BST and AVL

Before looking at the B-tree and B + tree, first look at the binary search tree (BST) and balanced binary tree (AVL).

In the sequential storage structures (e.g., arrays), the fastest case is a first target value, the worst case is the last target value, assuming there are n elements, with a large O notation average time complexity is O (n).

Use binary search tree can effectively optimize the search time. Using the binary search tree properties left child node is smaller than the parent, the right child is greater than the parent, can easily be binary search, effectively optimize the search time.

Here Insert Picture Description
Under normal circumstances, we can use binary search tree, but if the situation arises, binary search tree but not achieve results, the average search time complexity is still O (n).

Here Insert Picture Description
Introducing balanced binary tree, the difference in depth not more than 1, thereby ensuring not inclined, or shorter, to ensure its searching efficiency.

B-tree and B + tree

Since it has been balanced binary tree can speed up queries, but in fact does not use InnoDB. When thinking about issues related to B-tree and B + tree, is inseparable from a problem - disk IO. Index files stored on the disk, assuming balanced binary tree height of 30, then you might want to scan the disk 30 times to complete the search.

对于需要磁盘IO的情况,使用平衡二叉树依旧比较糟糕,所以需要引入多路树,即B树和B+树,使得树更“矮”。

Here Insert Picture Description
如果上述B树改成二叉树,那么树的高度就大了很多,换而言之就需要更多次的磁盘IO。

B+树是B树的变种。B+树的非叶子结点不存储数据,并且所有的叶子节点以双向链表的形式相连。

Here Insert Picture Description
现在的索引模型基本都是B+树。

相对于B树来说,B+树的搜索更加稳定,因为B树有的数据是分布在非叶子节点上的。

B树的叶子节点以链表的形式相连且按照规则排了序,通过B+索引,可以更加方便的获取范围数据。

这也是不使用哈希索引的原因。虽然哈希索引搜索的时间复杂度为O(1),但大部分时候我们并不会只查询一条记录,这种时候使用哈希索引就比较乏力了。

聚集索引

聚集索引,亦可称为主键索引。一张表只存在一个聚集索引。

聚集索引是根据其主键作为排序规则的B+树,搜索时根据其主键进行搜索。

其中叶子节点上存储着整条记录的数据。

InnoDB的B+树在磁盘中的存储是以数据页的形式,在树中间进行插入和删除操作涉及列“页分裂”和“页合并”的复杂过程(关于这点我个人也讲不明白,但可以类比AVL树的旋转去理解),十分耗性能,而直接插入尾部是比较快捷的方式,所以在很多的规范中写道,当使用InnoDB引擎的时候,强烈建议用一个与业务无关的自增id作为主键。

此外,删除也是一样的,很多时候会要求做伪删除,不仅仅只是为了数据分析,更是为了索引的性能。

非聚集索引

非聚集索引又称辅助索引,以非主键列来建立。非聚集索引可以有多个。非聚集索引和聚集索引的区别在于,非聚集索引的叶子节点并不存储整条记录的数据,而是存储指向的主键的指针。所以,当利用非主键索引进行搜索时,还需要通过主键索引获取整条数据。

单值索引
单值索引就是在数据表单个列上建立单个值。

CREATE INDEX index_name ON table_name(column);

与主键索引类似,单值索引按照所指定列排序建立二叉树。当利用单值搜索到目标后,再通过主键索引去读取整条数据。

唯一索引
唯一索引与单值索引区别不大,只是唯一索引的值不会重复。

唯一索引除了能提高一些效率以外,有时也用来保证列的唯一性,如用户的手机号身份证等。这里不做过多赘述。

联合索引
创建联合索引时指定多列即可。

CREATE INDEX index_name ON table_name(column1, columm2, column3 [,...])

联合索引会按照建立索引时的顺序,对每个字段进行排序。即第一个字段排完序,接着排第二个字段,第三…
Here Insert Picture Description
覆盖索引

在前面提到,非聚集索引搜索记录时还需要通过的主键索引,但如果查找的列刚刚好是联合索引的字段,那就没有必要去再去搜索主键索引,直接取叶子节点值即可,这就是覆盖索引。

为什么不用select *,原因就在此,不仅仅是为了减少读取更多列带来的开销,也是为了能够使用上覆盖索引。使用覆盖索引可以减少磁盘IO,有效提高性能。

下文将讲述有关联合索引的更多细节。

最左前缀原则

上文了解了联合索引,知道了联合索引的节点数据是按照建索引的顺序依次排序,由此我们引出了最左前缀原则,联合索引中,如果要用上索引字段,前面的字段不能跳过。如果上图的例子,假设是找column2=“ccc”的记录,大概的sql如下

SELECT some_column FROM table_name WHERE column2="ccc"

这种情况下索引是用不上的,因为索引是先排序的column1,再排序column2,直接通过column2搜索,B+树并不知道怎么搜索。
索引失效

除了上述的最左前缀原则下索引的失效,还有其他索引失效情况。

使用MySQL内置函数运算的列索引会失效。

使用!=,is null,is not null 索引会失效。
比如你查找id != 500的记录,相当把扫描id<500,以及id >500的记录,本质上全表扫描没啥区别。

范围查询后的列无法使用。
还是用上图的例子,假设查询 column1 <= 4的情况

SELECT some_column FROM table_name WHERE column1 <= 4

因为column1是排了序的,索引联合索引column1还是可以使用上的,但column1是范围数据,在这范围内column2并不有序。

以通配符开头的模糊查询(LIKE “%string”)。
值得一提的是,LIKE "string%"是能用上索引的,类似于范围查询,查询从string开头的最小字符串到stirng开头的最大字符串。知道了LIKE "string%"是能用上索引的就能理解为什么LIKE "%string"为什么用不上索引了。

还有其他情况的情况,可用MySQL的查询分析器进行分析。

InooDB使用的锁是行锁,但如果在更新时索引失效了,行锁会变成表锁,在开发中应该避免。

索引使用tip

常用来分组和排序的字段可建立索引。
索引的作用是查询和排序,order by和group by是可以用上索引的,如果排序的有多字段,也是按照最左前缀原则。

经常用来查询的字段可建索引。

更新频繁的字段不要建立索引。
频繁更新的字段如果建立来索引,更新时不仅更新数据,而且索引的B+树也会发生变化,开销比较大,得不偿失。

选择性小的列不要建立索引。
比如说性别字段,只有男或女或未知,百万数据里只有这三个值,建立索引毫无意义。

索引尽量使用等值匹配。

尽量使用覆盖索引。

小结

通过建立索引,可以有效的加速数据库的查询和排序。当谈及的数据库优化时,索引优化肯定跑不了。索引的使用有各业界大佬总结的技巧,但很多东西不是绝对的,不能以偏概全,在大数据以及复杂业务下,索引的维护算是玄学,需要不断寻找最佳的索引方案。

以上内容都是我自己的一些感想,分享出来欢迎大家指正,顺便求一波关注,有想法的伙伴可以评论或者私信我哦~
Here Insert Picture Description

Published 22 original articles · won praise 7 · views 7609

Guess you like

Origin blog.csdn.net/ZYQZXF/article/details/104557302