(3)mysql index

生活中的索引

最常见的书籍是有目录的,也可以叫做为索引。


为啥用索引?

为快不破,为了快速的查找到我们想要的东西,书中的索引可以快速查询到我们想看的章节内容。DB中的索引亦是如此。


索引本质

本质就是查找算法和数据结构,学过很多查找算法,顺序查找、二分查找、归并查找等等,如果DB不加索引就是对全表进行扫描,所说的全表扫描就是顺序查找。而mysql InnoDB中的索引就是有二分查找算法中的二分思想,二分查找是需要数据的排列是有序的
索引是对数据表中的一个或者多个列进行排序的数据结构,以协助快速查询、更新数据库表中数据。


mysql索引类型

B+ 树索引
全文索引
哈希索引
常用的和最有效的是B+树索引,本篇主要说B+树索引

磁盘IO与预读

考虑到磁盘IO是非常昂贵的操作,计算机操作系统做了一下优化,当一次IO时,不仅把当前磁盘地址的数据读取到内存缓冲区,也会把相邻的数据也会读取到缓存区。因为当计算机访问一个地址的时候,与其相邻的数据也会很快被访问到,每一次IO读取称为一页。

mysql一个区中有多少页被顺序访问时,InnoDB存储才启用预读?
我们可以查看参数innodb_read_ahead_threshold

mysql> show variables like 'innodb_read_ahead_threshold';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| innodb_read_ahead_threshold | 56    |
+-----------------------------+-------+
1 row in set (0.01 sec)

当一个区中的56个页已经被访问过并且为顺序访问的,则会预读下一个区的所有页。(来自《mysql内幕 InnoDB存储引擎》)


B+树索引

B+树索引的构造类似于二叉树,根据(key value)快速找到数据。
B+数(balance Tree)能找到被查找数据所在的页。然后数据库通过把页读入到内存再在内存中进行查找,最后得到要查找的数据。

索引是对数据表中一个或者多个列的值进行排序的数据结构,以协助快速查询更新数据库表中的数据。索引加快了访问速度,因为存储引擎不会再去扫描整张表得到需要的数据;相反,他从根节点开始,根节点保存了子节点的指针,存储引擎会根据指针快速的寻找数据。)
(3)mysql index_第1张图片

非叶子节点: 不存储真实的数据,只存储指引搜索方向的数据项。
叶子节点:存储真实的数据,每个磁盘块中是一页,一页4k或8k

叶子和叶子之间:B+tree所有的叶子节点通过指针连接在一起

B+树的查找过程及其性质
例如查找3,从根节点开始查找,会把根节点的磁盘块加载到内存,此时会发生一次IO,然后根据磁盘块1的指针,找到磁盘块2,把磁盘块2加载到内存,然后通过指针指向找到磁盘块5,把磁盘块5加载到内存。
在内存中用二分查找法查找到3。所以找到3一共发生了三次IO,3层的b+树可以表示上百万的数据,如果上百万数据查找需要三次IO,性能将是很大的提高,如果索引顺序查找百万数据成本是非常高的。
一般索引要求索引字段越小越好,一页的大小是固定的,当索引字段(例如int bigint )所占字节大的,磁盘块中存放的数据就会少,树的高度就会越高,这样IO次数就会增加,反之就会减少

最左匹配原则
(A,B,C)组合索引,索引生效的是A AB ABC ,而AC只是A走索引了,C不会走索引,而BC也完全不会走索引。因为b+树是按照从左向右的顺序来建立搜索树的,只有当搜索到A才会搜索到B,才会找到C。也就是搜索的方向确定了,如果是AC,只会搜索到A,下一个字段B缺失了。

为什么B+树比B树更适合作为数据库和文件的索引?

数据库采用B+树为非B树: B+树只要遍历叶子节点就可以实现整棵树的遍历,而在数据库中基于范围的查找是非常频繁的,而B树查找只能用中序遍历,效率较低。
B+树查询效率稳定:叶子节点是索引,非叶子节点是指向,任何查找都是从根节点到叶子节点的路程,所以查找路径长度相同,每个数据的查询效率相当。


什么情况下需要建立索引?

1 、表的主键会自动添加上主键索引。
2、经常与其他表进行连接的字段,需要在这个字段上添加上索引。
3、经常出现在where字段后,特别是需要大表查询的,需要建立索引。
4、索引需要建立在小的字段上,对于大文本或者超长的字段不要建立索引。
5、复合索引建立需要仔细分析;尽量用单字段索引代替。
6、如果复合索引中包含的字段超过3个,考虑必要性,考虑减少复合自断。
7、复合索引字段是否经常以and方式出现在where字句中?单个查询是否极少或者没有?如果是,则建立复合索引,否则需要建立单个索引。
8、经常出现在order by 、group by、distinct后面字段。


索引注意事项

以”%”号开头的like模糊匹配语句,不会走索引。
or语句前后没有同时使用索引。
类型出现隐式转换,不会使用索引。
最左匹配原则。


索引分类

普通索引和唯一索引:索引列值唯一性
单个索引和复合索引:索引列包含的列数
聚集索引和非聚集索引:
聚集索引的叶子节点是数据页、每个页通过一个双链表来进行链接的;聚集所以不是物理上连续,而是逻辑上的连续。
非聚集索引(辅助索引):叶子节点除了包含键值外,每个叶节点还包括一个书签。当通过非聚集索引叶子节点的指针,来指向主键索引的主键,然后通过主键索引来找一个完整的行记录。(通过非聚集索引找到聚集索引)


索引与磁盘

我们知道固态硬盘的读写速度要大于普通的机械硬盘。mysql数据库使用ssd呢?

http://fewstreet.com/2014/01/06/mysql-hard-disk-vs-SSD-performance.html
但是也有文章说放到ssd上并没有很大的效果,可能是我们的索引数据结构在机械硬盘和固态硬盘上并没有什么差别,没有利用固态硬盘的优势。

https://blog.2ndquadrant.com/tables-and-indexes-vs-hdd-and-ssd/
而且固态硬盘数据不容易恢复,价格也比普通的机械硬盘昂贵。

书上这样说的,

固态硬盘的接口规范、定义、功能和使用等方面与传统机械硬盘相同,但是他们的内部构造完全不同,固态硬盘没有读写磁头,读取数据需要围绕中心轴旋转,因此,在随机读取性能上有了质的飞跃

mysql官方文档:https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-diskio.html

欢迎留言讨论哈

参考:http://blog.csdn.net/justloveyou_/article/details/78308460
参考:https://tech.meituan.com/mysql-index.html

参考:
https://mp.weixin.qq.com/s?__biz=MzI2NjA3NTc4Ng==&mid=2652079363&idx=1&sn=7c2209e6b84f344b60ef4a056e5867b4&chksm=f1748ee6c60307f084fe9eeff012a27b5b43855f48ef09542fe6e56aab6f0fc5378c290fc4fc&scene=0&pass_ticket=75GZ52L7yYmRgfY0HdRdwlWLLEqo5BQSwUcvb44a7dDJRHFf49nJeGcJmFnj0cWg#rd

你可能感兴趣的:(【mysql】)