如何通过索引让SQL查询效率最大化?

前言

我们都知道SQL性能调优可以从两个维度去进行优化,一个逻辑查询优化,另一个是物理查询优化。逻辑查询优化就是通过SQL等价变换提升查询效率,直白一点就是说,换一种查询写法执行效率可能更高。物理查询优化则是通过索引和表连接方式等技术来进行优化。当谈到通过索引去优化SQL查询效率,首先我们需要知道创建索引有哪些规律。

创建索引有哪些规律?

创建索引有一定的规律。当这些规律出现的时候,我们就可以通过创建索引提升查询效率。

哪些情况下可以创建索引:

1、字段的数值有唯一性的限制,比如用户名
索引本身可以起到约束的作用,比如唯一索引,主键索引都是可以起到唯一性约束的。在数据表中,如果某个字段是唯一性的,就可以直接创建唯一性约束,或者主键索引。
2、频繁作为 WHERE 查询条件的字段,尤其在数据表大的情况下
3、需要经常 GROUP BY 和ORDER BY 的列
4、UPDATE 、DELETE 的 WHERE 条件列,一般也需要创建索引
5、DISTINCT 字段需要创建索引
做多表JOIN连接操作时,创建索引需要注意以下原则:

  • 连接表的数量尽量不要超过3张,因为每增加一张表就相当于增加了一次嵌套的循环,数量级增长会非常快,严重影响查询的效率
  • 对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致。
    举例:
    下面这条SQL使用了JOIN 连接,那么ON 左右两侧的字段user_id在product_comment表和在user表中的字段类型必须一致,而不能一个为int另一个为varchar类型。
SELECT comment_id, comment_text, product_comment.user_id, user_name FROM product_comment JOIN user ON product_comment.user_id = user.user_id
WHERE comment_text = '462eed7ac6e791292a79'

哪些情况下不需要创建索引:

索引不是万能的,有一些情况是不需要创建索引的,比如:
1、WHERE 条件(包括GROUP BY 、ORDER BY)里用不到的字段不需要创建索引,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的。
举例:

SELECT comment_id, product_id, comment_time FROM product_comment WHERE user_id = 41251

上面这条SQL是按照user_id来进行检索的,所以不需要对其他字段创建索引,即使这些字段出现在 SELECT 字段中。
2、表记录太少,比如少于1000个,那么是不需要创建索引的。表记录太少,是否创建索引对查询效率的影响并不大。
3、字段中如果有大量重复数据,也不用创建索引,比如性别字段。除此之外还需要考虑数值的分布情况。
4、频繁更新的字段不一定要创建索引。因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候也会造成负担,从而影响效率。

什么情况下索引失效

常见的索引失效的例子:
1、如果索引进行了表达式计算,则会失效。
例如:
对comment_id添加了索引,如果SQL执行的过程中对这个字段进行了表达式计算那么索引就会失效。

SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id+1 = 900001

2、如果对索引使用函数,也会造成失效。
例如:
对comment_text 字段添加了索引,如果SQL执行的过程中对这个字段进行了substring函数运行,那么索引就会失效。

 SELECT comment_id, user_id, comment_text FROM product_comment WHERE SUBSTRING(comment_text, 1,3)='abc'

3、在WHERE 子句中,如果在OR 前的条件列进行了索引,而在 OR 后的条件列没有进行索引,那么索引会失效。
因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效。
例如:

 SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id = 900001 OR comment_text = '462eed7ac6e791292a79'

4、当我们使用LIKE 进行模糊查询的时候,后面不能是 % 。

例如:
这个很好理解,如果一本字典按照字母顺序进行排序,我们会从首位开始进行匹配,而不会对中间位置进行匹配,否则索引就失效了。

 SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_text LIKE '%abc'

5、索引列尽量设置为 NOT NULL 约束。
这样做的好处是可以更好的使用索引,节省空间,甚至加速SQL的运行。
判断索引列是否为 NOT NULL ,需要走全表扫描,因此最好在设计表的时候就将字段设置为NOT NULL约束。
比如可以将INT类型的字段,默认值设置为0。将字符类型的默认值设置为空字符串(’ ')。
6、在使用联合索引的时候要注意最左原则
最左原则就是需要从左到右的使用索引中的字段,一条SQL语句可以只使用联合索引的一部分,但是需要从最左侧开始,否则就会失效。

总结

使用好索引可以提升SQL查询的效率。需要注意的是添加索引的数量不是越多越好,索引也是会占据空间的,所以尽可能的扩展索引,而不是新建索引。而且索引数量越多需要维护的成本也会变大,导致写效率变低。同时我们还需要定期查询使用率低的索引,对于 从未使用过的索引可以进行删除,这样才能让索引在SQL查询中发挥最大价值。

本文内容参考极客上的课程,欢迎大家在评论区进行交流~

发布了184 篇原创文章 · 获赞 200 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Sophia_0331/article/details/105222801