索引是一个比较复杂的模块,要学好需要多花点时间。索引是MySQL进行查询优化的一个很重要的手段,如果用得好,可以成为数据访问的有力而且灵活的工具,快速提高查询效率,所以多花点时间好好学习和思考这一块内容也是很值得的。下面,对MySQL中索引的内容做了一下归纳总结,有点零散。
1、索引是存储引擎用于快速找到记录的一种数据结构。
2、索引是对查询性能优化最有效的手段。
3、B-树索引能够加快访问数据的速度,因为存储引擎不再需要进行全表扫描来获取需要的数据,取而代之的是索引的根节点开始进行搜索。根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找。通过比较节点页的值和要查找的值可以找到合适的指针进入下一层子节点,这些指针实际上定义了子节点页中值的上限和下限。最终存储引擎要么是找到对应的值,要么该记录不存在。
4、B-树对索引列是顺序组织存储的,所以很适合查找范围数据。
5、使用B-树索引适用于全键值、键值范围或键前缀查找。具体地:
(1)全值匹配
(2)匹配最左前缀
(3)匹配列前缀
(4)匹配范围值
(5)精确匹配某一列并范围匹配另一列
(6)只访问索引的查询
6、如果不是按照索引的最左列开始查找,则无法使用索引。
7、不能跳过索引中的列。
8、如果查询中有某个列的范围查找,则其右边所有列都无法使用索引优化查找。
9、哈希索引:对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。
10、在MySQL中,只有Memory引擎显式支持哈希索引。
11、不能使用哈希索引中的值来避免读取行。
12、哈希索引无法用于排序。
13、哈希索引不支持索引列匹配查找。
14、哈希索引只支持等值比较查询,不支持范围查询。
15、创建自定义的哈希索引:在B-Tree基础上创建一个伪哈希索引,使用哈希值而不是键本身进行索引查找。需要在查询的WHERE子句中指定哈希函数。
16、不要使用SHA1()和MD5()作为哈希函数,因为计算出来的哈希值是非常长的字符串。
17、SHA1()和MD5()是强加密函数,设计目标是最大限度消除冲突。
18、空间数据索引(R-Tree)用于存储地理数据。
19、全文索引查找文本中的关键词。
1、索引的优点有三个:
(1)大大减少服务器需要扫描的数据量。
(2)帮助服务器避免排序和临时表。
(3)将随机I/O变为顺序I/O。
2、三星系统,用于评价一个索引是否适合某个查询:索引将相关的记录放到一起则获得一星;如果索引中的数据顺序和查找中的排列顺序一致则获得二星;如果索引中的列包含了查询中需要的全部列则获得三星。
1、独立的列:索引列不能是表达式的一部分,也不能是函数的参数。
2、索引的选择性:不重复的索引值(也称为基数)和数据表的记录总数(#T)的比值。
3、前缀索引是能够使索引更小、更快,缺点是:MySQL无法使用前缀索引做ORDER BY和GROUP BY,也无法做覆盖扫描。
4、索引合并策略:查询能够同时使用两个单列索引进行扫描,并将结果进行合并。这种算法有三个变种:OR条件的联合,AND条件的相交,组合前两种情况的联合及相交。
5、当出现服务器对多个索引做相交操作时(通常有多个AND条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引。
6、当不需要考虑排序和分组时,将选择性最高的列放到索引最前列。
7、聚簇:表示数据行和相邻的键值紧凑地存储在一起。
8、一个表只能有一个聚簇索引。
9、叶子页包含了行的全部数据,节点页只包含了索引列。
10、InnoDB的聚簇索引来源:主键、唯一的空索引、隐式定义一个主键。
11、聚簇索引的优点:
(1)可以把相关数据保存在一起。
(2)数据访问更快。
(3)使用覆盖索引扫描的查询可以直接使用叶节点中的主键值。
12、聚簇索引的缺点:
(1)如果数据全部放在内存中,访问的顺序就没那么重要了。
(2)插入速度严重依赖插入顺序。
(3)更新聚簇索引列的代价很高。
(4)插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂”。
(5)可能导致全表扫描变慢,或者由于页分裂导致数据存储不连续。
(6)二级索引可能比想象的要更大。
(7)二级索引访问需要两次索引查找。
13、MyISAM按照数据插入的顺序存储在磁盘上。
14、因为行是定长的,所以MyISAM可以从表的开头跳过所需的字节找到需要的行。
15、在InnoDB中,聚簇索引就是表,不需要MyISAM那样需要独立的行存储。
16、InnoDB二级索引的叶子节点中存储的是主键值,并以此作为指向行的“指针”。
17、在InnoDB表中按主键值插入行,最简单的方法是使用AUTO_INCREMENT自增列。
18、对于高并发负载,在InnoDB中按主键顺序插入可能会造成明显的争用,主键的上界和AUTO_INCREENT锁机制可能会成为热点。
19、覆盖索引:一个索引包含(或者说覆盖)所有需要查询的字段的值。
20、覆盖索引的优点:
(1)减少数据访问量。
(2)I/O密集型的范围查找会比随机从磁盘读取每一行数据的I/O要少的多。
(3)InnoDB二级主键如果能够覆盖查询,可以避免主键索引的二次查询。
21、MySQL只能使用B-Tree索引做覆盖索引。
22、在大多数存储引擎中,覆盖索引只能覆盖那些只访问索引中的部分列的查询。
23、MySQL有两种方式可以生成有序的结果:通过排序操作;或者按索引顺序扫描。
24、只有当索引的列顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向都一样时,MySQL才能够使用索引来对结果做排序。如果查询需要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能使用索引做排序。ORDER BY子句需要满足索引的最左前缀的要求。
25、压缩(前缀压缩)索引:默认只压缩字符串,通过参数设置也可以对整数做压缩。
26、MyISAM压缩每个索引块的方法:先完全保存索引块中的第一个值,然后将其他值和第一个值进行比较得到相同前缀的字节数和剩余的不同后缀部分,把这部分存储起来即可。
27、重复索引:在相同的列上按照相同的顺序创建的相同类型的索引。应该避免这样创建重复索引。
28、MySQL的唯一限制和主键限制都是通过索引实现的。(容易造成重复索引)
29、如果创建了索引(A,B)再创建索引(A)就是冗余索引,因为这只是前一个索引的前缀索引。
30、应该尽量扩展已有的索引而不是创建新的索引。
31、一般来说,增加新索引将会导致INSERT、UPDATE、DELETE等操作的速度变慢。
32、InnoDB只有在访问行的时候才会对其加锁,而索引能够减少InnoDB访问的行数,从而减少锁的数量。
33、InnoDB在二级索引上使用共享(读)锁,但访问主键索引需要排他(写)锁。
1、在有更多不同值的列上创建索引的选择性会更好。
2、避免多个范围条件,可以使用IN()代替。(MySQL无法使用范围列后面的其他索引列,IN()本质上是等值查询)
05、维护索引和表
维护索引和表主要有三个目的:(1)找到并修复损坏的表;(2)维护准确的索引统计值;(3)减少碎片。