5.1索引基础《创建高性能的索引》
索引:也叫KEY,储存引擎中快速找到记录的数据结构
数据量越大,越重要,查询性能优化最有效手段。
用法:在索引中找到对应值,再找到对应的数据行
ORM也要关心索引,再复杂的ORM在精妙复杂的索引面前都是浮云
类型:B-Tree树、hash索引
一、B-Tree树
没特别指出类型时,一般说的都是它。
除了Archive,大多数Mysql引擎都支持这种索引
创建表时,也用这个关键字,但底层结构可能不同,NDB集群用T-tree,InnoDB用的B+tree
特点:
按顺序存储,每个叶子到根距离相同,速度快,不用全表扫描,从根节点搜索。
(1)非叶子节点存储:索引列值以及左范围和右范围
(2)叶子节点存储的是指向数据行的指针
(3)适用于:全键值、键值范围、键值前缀查找
1.全值匹配:和索引中的所有列进行匹配。
2.匹配最左前缀:对于一个索引包含多个列,只使用索引的第一列。
3.匹配列前缀:第一列name字段的时候,以J开头的姓名
4.匹配范围值:某一个范围内的记录,只用第一列。
5.精确匹配某一列并范围匹配另外一列:精确匹配第一列,第二列范围匹配。
6.只访问索引的查询:访问索引行,不访问记录中其余字段的数据行。
索引树中的节点是有序的,除了按值查找,还可以按顺序查找order by
使用限制:
(1)只能从最左列开始查找,且无法查找姓氏以某个结尾的人
(2)不能跳过索引中的列
(3)查询中有某个列的范围查找,则其右边所有列都无法使用索引优化,用LIKE,LIKE右侧索引失效
二、Hash哈希索引
基于哈希表实现,只有精确匹配索引所有列的查询才有效。每行数据存储引擎计算一个哈希码,哈希码是一个较小的值,每行不一样
结构紧凑,查找速度非常快
1)只存储哈希值和行指针,并不存储具体的字段值,所以一定会存在读取行的过程。
2)无法用于排序:不是按照索引值顺序存储的
3)只支持等值比较查询(=、IN()、<=>相当于=,有null时用)不支持范围比较查询
4)哈希冲突的数据:必须遍历链表中的所有行指针(所有相同hash记录),即常量值比较
5)有哈希冲突,索引维护操作的代价高
InnoDB有一个“自适应哈希索引”功能,索引值使用频繁时,基于B-Tree索引创建哈希索引。用户无法干预,顶多是关闭该功能。
自定义哈希索引:
B-Tree上创建伪哈希索引。使用B-Tree进行查找,使用哈希值而不是键本身索引查找。查询where指定使用哈希函数就Ok:
如URL(太长)可以增加crc值作为哈希值索引,创建触发器及时更新索引列
注:不要用SHA1()、MD5()作为哈希索引,大且慢
处理hash冲突
mysql>select * from words where crc=crc32(‘gnu’) and word=’gnu’;
crc字段就是word字段哈希之后的值,带上原本的值做上二次比较,可精确定位。