本文探讨的索引均为查询为目的的索引。
索引的目的是什么?
索引的主要目的是为了加快查询速度。
索引如何加快查询速度呢?
- 对字段建立索引文件(或者在内存中建立索引对象),减少磁盘的 IO。
- 减少查询时扫描表的行数。
- 减少回表(例如索引覆盖,其实也是减少磁盘的 IO)
什么字段有建立索引的必要?
- 根据业务需求添加索引。
- 字段的值重复率低可以建立索引,例如用户ID。
再例如一些字段是bool类型的,且取值是true
false
各 50%,建立索引意义不大(索引行数相对全表只减少了一半),但是如果是true
是 1%,且业务查询的参数以true
居多,那么创建索引可以有效减少扫描行数。- 字段长度较短的,例如整数,长度在 191 字节以内的字符串类型字段
是不是查询条件包含索引字段和非索引字段就一定会全表扫描?
不是,例如
SELECT * FROM user_asset WHERE id = #{id} AND version = #{version}
,由于查询条件中有主键,所以 mysql 不会放弃使用主键索引。
此外SELECT
的ORDER BY
以及LIMIT
都会影响 MySQL 的执行计划。
联合索引是不是覆盖所有的查询的字段是最好的?
不是,减少索引扫描数据条目的数量是索引加快查询速度的一种方案。
例如查询条件是 key1, key2, key3, key4, 其中 key1 + key2 可以过滤掉 99.99% 的数据,
那么联合索引可以只加在 key1, key2 上。如果剩余的 0.01 %的数据量仍然很大,那么需要对表中的数据做分析,做出选择性更强的联合索引。
此外联合索引字段越多,更新插入的效率越差,需要在实际数据和业务查询上做平衡
此外索引建立的目的是为了加速查询,是为业务服务的,如果业务需求如此,那么一些索引设计的条条框框就要为业务作出让步。索引应该是实践至上,业务需求至上而不是教条主义。