创建索引有哪些规律?
- 字段的数值有唯一性的限制,比如用户名
- 频繁作为 WHERE 查询条件的字段,尤其在数据表大的情况下
- 需要经常 GROUP BY 和 ORDER BY 的列
- UPDATE、DELETE 的 WHERE 条件列,一般也需要创建索引
- DISTINCT 字段需要创建索引
- 做多表 JOIN 连接操作时,创建索引需要注意以下的原则
- 连接表的数量尽量不要超过 3 张
- 对 WHERE 条件创建索引
- 对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致
什么时候不需要创建索引
- WHERE 条件(包括 GROUP BY、ORDER BY)里用不到的字段不需要创建索引
- 表记录太少,比如少于 1000 个,那么是不需要创建索引的
- 字段中如果有大量重复数据,也不用创建索引
- 频繁更新的字段不一定要创建索引
什么情况下索引失效
- 如果索引进行了表达式计算,则会失效
EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id+1 = 900001
好的写法:
SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id = 900000
- 如果对索引使用函数,也会造成失效
EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE SUBSTRING(comment_text, 1,3)='abc'
好的写法:
SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_text LIKE 'abc%'
- 在 WHERE 子句中,如果在 OR 前的条件列进行了索引,而在 OR 后的条件列没有进行索引,那么索引会失效。
比如下面的 SQL 语句,comment_id 是主键,而 comment_text 没有进行索引,因为 OR 的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效
EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id = 900001 OR comment_text = '462eed7ac6e791292a79'
- 当我们使用 LIKE 进行模糊查询的时候,前面不能是 %
EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_text LIKE '%abc'
索引列尽量设置为 NOT NULL 约束
我们在使用联合索引的时候要注意最左原则
总结
实际工作中,查询的需求多种多样,创建的索引也会越来越多。这时还需要注意,我们要尽可能扩展索引,而不是新建索引,因为索引数量过多需要维护的成本也会变大,导致写效率变低。同时,我们还需要定期查询使用率低的索引,对于从未使用过的索引可以进行删除,这样才能让索引在 SQL 查询中发挥最大价值。