如何分析和优化 SQL 性能?“EXPLAIN牌放大镜”助你一臂之力!

139 阅读8分钟

哈喽,各位小伙伴们,你们好呀,我是喵手。

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  采访下大家,你们是否曾经有碰到这样一个场景,面对一个“慢得像蜗牛”的 SQL 查询束手无策?看着页面加载缓慢,心里怒火中烧,却无从下手优化?如果有,那么你可以看看我这篇总结,如果你当时没解决或者解决时长久,那只能说明是没用好的工具和方法!

  今天,我们就来聊聊 SQL 优化的利器——EXPLAIN 语句。EXPLAIN 它就好比是数据库优化的“放大镜”,它能揭示 SQL 执行的底层逻辑,从扫描表到使用索引,所有的细节都一目了然,走没走索引,索引有没有失效,都可以通过该命令进行查验。再则你通过学习 EXPLAIN命令,便有实力分析 SQL 性能,并找到优化的方向,优化慢SQL🔥

目录

  1. 什么是 EXPLAIN 语句?
  2. EXPLAIN 的核心字段解析
  3. SQL 优化的实际案例
  4. 优化技巧:让查询效率翻倍!
  5. EXPLAIN 的局限性与注意事项
  6. 总结与最佳实践

什么是 EXPLAIN 语句?

EXPLAIN 的定义

  什么是 EXPLAIN 语句?如果是针对没有用过的小伙伴,这绝对是一大疑问。EXPLAIN ,它是一种 SQL 语句,用来展示查询执行计划。简单来说,使用它可以告诉你如下信息:

  • 数据库是如何执行你的 SQL 查询的;
  • 哪些表被扫描了;
  • 是否使用了索引;
  • 查询的性能瓶颈在哪里。

  你只需要在查询前加上 EXPLAIN,就能看到数据库的“操作剧本”。

示例演示如下:

image.png

语法示例

  接下来,我给大家特地讲解下该命令的语法,比如说如下SQL:

EXPLAIN SELECT * FROM orders WHERE order_status = 'completed';

  执行后,数据库会返回一张表,里面包含了执行计划的各种细节,比如扫描的表、使用的索引、扫描的行数等。

image.png

为什么 EXPLAIN 如此重要?

  那大家肯定会想了,EXPLAIN 重要吗?为什么它可以在SQL优化中占有如此之重的成分,如下几个点概括让你明白:

  1. 可视化执行过程:它像是 SQL 的“黑匣子”,揭示你看不到的执行逻辑。
  2. 发现性能瓶颈:比如全表扫描、索引失效等问题,一眼就能看出来。
  3. 优化依据:根据 EXPLAIN 的结果,可以有针对性地改写 SQL 或调整索引。

EXPLAIN 的核心字段解析

  这里,我们根据如上的演示SQL,可以清楚看到SQL执行后返回了很多字段,那么在EXPLAIN 的结果表中,有几个关键字段是我们优化的重点,下面我来进行逐一讲解,大家请看。

1. id

  • 定义:查询的执行顺序。id 越大,优先级越高。
  • 优化方向:尽量让复杂的子查询在高优先级执行。

2. select_type

  • 定义:查询的类型,例如简单查询、子查询、联合查询等。
  • 常见类型
    • SIMPLE:简单查询。
    • PRIMARY:主查询。
    • SUBQUERY:子查询。
  • 优化方向:避免复杂的嵌套子查询,尽量将子查询改写为 JOIN。

3. table

  • 定义:当前操作的表名。
  • 用途:帮助你定位查询过程中涉及的表。

4. type

  • 定义:访问类型,表示查询扫描数据的方式。
  • 常见值(按效率从高到低排序)
    • system:系统表(效率最高)。
    • const:一次扫描定值。
    • ref:使用非唯一索引。
    • ALL:全表扫描(效率最低)。
  • 优化方向:尽量避免 ALL 类型的扫描。

5. possible_keys

  • 定义:查询中可能使用的索引。
  • 优化方向:如果为空,说明没有可用的索引,可以考虑添加索引。

6. key

  • 定义:实际使用的索引。
  • 优化方向:确保查询用到了合适的索引。

7. rows

  • 定义:数据库估计需要扫描的行数。
  • 优化方向:扫描行数越少越好。

8. Extra

  • 定义:额外信息。
  • 常见值
    • Using index:查询覆盖了索引(效率高)。
    • Using where:使用了 WHERE 条件。
    • Using temporary:使用临时表(性能较差)。
    • Using filesort:需要排序(性能较差)。
  • 优化方向:避免 Using temporaryUsing filesort

SQL 优化的实际案例

  接下来,我们通过一个实际案例,展示如何用 EXPLAIN 分析和优化 SQL。

问题 SQL

  假设我们现在有一张订单表,需求就是:要你查询最近 30 天完成的订单,那么SQL可以怎么写,模仿给大家看下:

SELECT * FROM orders WHERE order_status = 'completed' AND order_date >= '2023-11-01';

  是吧,看着sql非常简单,也没啥复杂的,但是...

执行 EXPLAIN

  我们加上EXPLAIN 执行试试,大家请看:

EXPLAIN SELECT * FROM orders WHERE order_status = 'completed' AND order_date >= '2023-11-01';

结果:

idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEordersALLNULLNULL10000Using where

分析问题

  根据如上执行结果,我们来重点来分析下:

  • type = ALL:表示进行了全表扫描,效率极低的行为。
  • possible_keys 和 key 为空:说明没有可用索引。
  • rows = 10000:表示数据库需要扫描所有行。

优化 SQL

  那么,既然我们定位到了这段SQL的痛点所在,那我们就可以进行对症下药了。比如说:添加索引等。

1. 添加索引

  为 order_statusorder_date 创建复合索引:

ALTER TABLE orders ADD INDEX idx_status_date (order_status, order_date);

2. 再次执行 EXPLAIN

  添加索引后,我们再次执行SQL,可以看看会发生啥,有哪些变化。

EXPLAIN SELECT * FROM orders WHERE order_status = 'completed' AND order_date >= '2023-11-01';

优化后结果:

idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEordersrefidx_status_dateidx_status_date500Using where

优化效果

  可以看到确实有变化,比如:

  • type 变为 ref:使用了索引,效率提升。
  • rows 降到 500:扫描行数减少 95%。

  是不是超级好用,只需要通过它这个放大镜,就能帮你把SQL调优给整OK。

优化技巧:让查询效率翻倍!

  接下来,我便给大家总结了我近几年开发以来,掌握的一些优化SQL的建议。

1. 用好索引

  • 索引是优化 SQL 的核心。确保 WHERE 子句中的字段使用索引。
  • 对于多条件查询,优先创建复合索引。

**2. 避免 SELECT ***

  • 只查询需要的字段,减少 I/O 和内存开销。

3. 减少嵌套子查询

  • 将子查询改为 JOIN,提高效率。

4. 拆分大表

  • 如果表过大,可以考虑按时间或业务拆分表,减少单表数据量。

5. 避免函数操作字段

  • 在 WHERE 子句中避免对字段使用函数或表达式,否则索引会失效。

EXPLAIN 的局限性与注意事项

  虽说EXPLAIN可以帮你定位SQL是否为慢SQL且进行SQL分析,但是它却不是万能的,有些点还是不适用,比如说它无法反映高并发情况下的性能等。

局限性

  1. 无法展示并发情况:EXPLAIN 仅展示单条查询的执行计划,不反映高并发情况下的性能。
  2. 估算结果:EXPLAIN 的行数和索引选择是数据库的估算结果,不一定完全准确。

注意事项

  • 在实际环境中测试优化效果,而不是仅依赖 EXPLAIN。
  • 定期更新统计信息,确保数据库优化器的决策更准确。

总结

  EXPLAIN 是 SQL 性能分析的强大工具,它可以够帮助我们:

  1. 了解查询的执行逻辑。
  2. 找到性能瓶颈。
  3. 制定针对性的优化方案。

  优化 SQL 的核心是无非就是减少无效扫描、用好索引、避免性能浪费等。最后,希望通过这篇文章,你能够掌握 EXPLAIN 的使用方法,并将它运用到实际项目中。记住哈,健康的 SQL 不仅运行快,还让团队的运维人员少掉几根头发!✨哈哈哈,我之前就调优过一段几百行的SQL语句,简直是要命。

  OK,如果你还有任何疑问或者更好的优化经验,欢迎留言交流!🎉

... ...

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

... ...

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。