索引
mysql索引有btree 和 hash 索引
1 | 2 | 3 | 4 | 5 | 6 | 7 |
假如 查询 where id = 5
如果在没有索引情况下:就需要从1开始对比到5;
假如要是id = 7 ,就需要从1对比到7,这样是非常消耗时间的
假如用btree索引
假如用hash索引
在内存中默认都是hash索引,hash的理论查询时间为0
既然hash这么高效为什么不都用hash索引那?
1 hash 函数计算后的结果是随机的,数据会被随机放到磁盘中
2 无法对范围查询进行优化 例如:id>5
3 无法利用前缀索引
4 排序也无法优化 gorder by
hash 存取值的过程:
首先通过hash函数 给值计算一个存储地址,然后让值存在哪里
当取值的时候,把值在用 hash函数计算,得到存储地址,然后直接取值,因此它是取值的最快方式
btree的常见误区:
1 在where 条件常用的列上都加上索引 这是错误的
因为是独立索引,同时只能用一个
2 在多列上建立索引后,查询那个列,索引都将发挥作用
误区: 多列索引发挥作用,必须满足左缀要求
以 index(a,b,c) 为例:(注意和顺序有关) 联合索引
语句 | 索引是否发挥作用 |
where a=3 | 是,只使用了a列 |
where a=3 and b=5 | 是,只使用了a,b列 |
where a=3 and b=5 and c=4 | 是,只使用了a,b,c列 |
where b=3 / where c= 4 | 否 |
where a=3 and c=4 | a列能发挥索引,c不能 |
where a=3 and b>5 and c=4 | a能用到,b能用到,c不能 |
同上,where a=3 and b like 'xx%' and c=4 | a能用到,b能用到,c不能 |
联合索引的理解
可以把a,b,c当做木板过桥
理想加索引条件
1查询频繁
2 区分度高
3 长度小
4 尽量能覆盖常用查询字段
对于查询的列中如果值真的比较长,采取从左往右截取部分,来建索引
1 截取的越短,重复率越高,区分度越小,索引效果不好
2 截取的越长 ,重复率底,区分度高,索引效果好,但是影响到性能,因此截取应适中
假如: word字段中存取的时 一串字符串,那么left(word,5) 代码截取前五个输出。
selec left(word,5) from dict
还有一种伪哈希索引的用法,因为查询字符串比较慢,可以使用crc32() 生成整型,存储到hash,当查询的时候把,值转成hash查询就可以了。
word | hash |
士大夫士大夫似的 | hash值 |
士大夫似的发士大夫 | hash值 |
多列索引
1 列的查询频率
2 列的区分度
3 列的查询顺序(结合实际业务场景)
例如是商场的话:顾客一般是先选大分类-->小分类-->品牌
索引和排序
1 innodb 是聚簇索引 假如使用了索引查询,查询的数据必然会顺序输出;
2 order by 排序时,最好使用索引列