MySQL索引相关
type
status
date
slug
summary
tags
category
icon
password
从数据结构角度
1、B+树索引(O(log(n))):关于B+树索引,可以参考 MySQL索引背后的数据结构及算法原理
2、hash索引:
a 仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询
b 其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引
c 只有Memory存储引擎显示支持hash索引
3、FULLTEXT索引(现在MyISAM和InnoDB引擎都支持了)
4、R-Tree索引(用于对GIS数据类型创建SPATIAL索引)
从物理存储角度
1、聚集索引(clustered index)
2、非聚集索引(non-clustered index)
从逻辑角度
1、主键索引:主键索引是一种特殊的唯一索引,不允许有空值
2、普通索引或者单列索引
3、多列索引(复合索引):复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合
4、唯一索引或者非唯一索引
5、空间索引:空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。
MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建
1、unique|fulltext|spatial为可选参数,分别表示唯一索引、全文索引和空间索引;
2、index和key为同义词,两者作用相同,用来指定创建索引
3、col_name为需要创建索引的字段列,该列必须从数据表中该定义的多个列中选择;
4、index_name指定索引的名称,为可选参数,如果不指定,MYSQL默认col_name为索引值;
5、length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度;
6、asc或desc指定升序或降序的索引值存储
避免索引失效
1). 全值匹配 ,对索引中所有列都指定具体值。该情况下,索引生效,执行效率高。
2). 左前缀法则如果索引了多列,要遵守左前缀法则。指的是查询从索引的左前列开始,并且不跳过索引中的列,否则索引失效。
1)匹配左前缀法则,走索引。结果也只是显示最后的匹配情况。2)如果符合左法则,但是出现跳跃某一列,只有左列索引生效。3). 范围查询右边的列,不能使用索引 ,否则破坏后面字段的索引。
4). 不要在索引列上进行运算操作, 索引将失效。
5). 字符串不加单引号,造成索引失效。【在查询是,没有对字符串加单引号,MySQL的查询优化器,会自动的进行类型转换,造成索引失效】
6). 尽量使用覆盖索引,避免select *尽量使用覆盖索引(只访问索引的查询(索引列完全包含查询列)如:select id from user,id是user的某个索引),减少select * 。
7). 用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。但是and不会受影响示例,name字段是索引列 , 而createtime不是索引列,中间是or进行连接是不走索引的8). 以%开头的Like模糊查询,索引失效。如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。【如果使用了,可以应用索引覆盖来解决。】
9). 如果MySQL评估使用索引比全表更慢,则不使用索引。
10). is NULL , is NOT NULL 有时索引失效
11). in 走索引, not in 索引也走索引
12). 单列索引和复合索引。尽量使用复合索引,而少使用单列索引
覆盖索引和索引下推
两者概念区别在于覆盖索引发生在索引数据查询完毕后要不要回表查询row_data,即select * 还是 column1,2,3。
索引下推发生在二级索引中,当查询条件均为联合索引中字段时,开启索引下推后不会在根据第一个索引数据拿到符合条件的row id后回表查找第二个条件的值,而是直接利用索引metadata进行比较
Next-Key lock and Gap lock
总结一句话,主键索引gap锁是前开后开,唯一索引和普通索引是前开后闭
情况比较多,一一列举
等值查询时:
如果值不存在
主键索引,唯一索引,普通索引均走间隙锁
如果值存在
主键索引 唯一索引退化为record lock,普通索引锁住(前一个最大值,后一个最小值)
范围查询时:
主键索引查询范围带=号时,MySQL的版本影响锁的范围,如id有1,4,6,8时,where id≥6会因8.0.25版本修复后,只锁住[6,8),而17之前的版本会锁住[4,8),
where id≥5时,新版本会锁住(4,6)区间,和主键的等值查询一致,老版本会锁住[4,6)
主键范围查询不带等号时,会锁住范围开区间
非主键唯一索引:
默认会锁住前开后闭区间
普通索引:
默认锁住前开后闭区间,如b有1,5,10,15,20,where b>5 and b≤10,会锁住(5,10],(10,15],即遵循没修bug之前的逻辑
特殊情况
MySQL加锁总结关于加锁补充一点小细节,在二级索引上,数据的组织格式是[普通索引,主键],而这就导致了gap 锁的范围是到主键下标为止!!!