SQL关联查询CPU占用100%,如何排查因缺失索引导致的嵌套循环问题?

2026-04-30 21:281阅读0评论SEO资讯
  • 内容介绍
  • 相关推荐

本文共计905个文字,预计阅读时间需要4分钟。

SQL关联查询CPU占用100%,如何排查因缺失索引导致的嵌套循环问题?

基本原因不是用了JOIN,而是执行计划选择了嵌套循环。外层驱动表返回大量行、内层被重复扫描无索引字段。每次外层返回一行,内层全表扫描一次,1万行×10万行=1亿次逻辑读,全压在CPU上做匹配和比较。

常见触发场景:LEFT JOIN 时左表没加WHERE过滤、ON条件里用了函数(如UPPER(a.name) = UPPER(b.name))、或内表连接字段完全没索引。

  • MySQL默认在小结果集驱动大表时倾向Nested Loop,但一旦驱动表实际返回行数远超预估(比如统计信息过时),就会失控
  • SQL Server和Oracle也会在缺失索引+低选择性条件下 fallback 到Nested Loops,尤其当优化器误判内表能走Index Seek却实际走了Index Scan
  • PostgreSQL在enable_nestloop=on且无可用Hash Join路径时,同样可能硬上嵌套循环

用EXPLAIN/SHOW PLAN快速识别缺失索引的嵌套循环

别猜,直接看执行计划里有没有“Rows远大于Actual Rows”或“Missing Index提示”,以及内表访问类型是不是ALL(MySQL)、Clustered Index Scan(SQL Server)或Seq Scan(PostgreSQL)。

阅读全文

本文共计905个文字,预计阅读时间需要4分钟。

SQL关联查询CPU占用100%,如何排查因缺失索引导致的嵌套循环问题?

基本原因不是用了JOIN,而是执行计划选择了嵌套循环。外层驱动表返回大量行、内层被重复扫描无索引字段。每次外层返回一行,内层全表扫描一次,1万行×10万行=1亿次逻辑读,全压在CPU上做匹配和比较。

常见触发场景:LEFT JOIN 时左表没加WHERE过滤、ON条件里用了函数(如UPPER(a.name) = UPPER(b.name))、或内表连接字段完全没索引。

  • MySQL默认在小结果集驱动大表时倾向Nested Loop,但一旦驱动表实际返回行数远超预估(比如统计信息过时),就会失控
  • SQL Server和Oracle也会在缺失索引+低选择性条件下 fallback 到Nested Loops,尤其当优化器误判内表能走Index Seek却实际走了Index Scan
  • PostgreSQL在enable_nestloop=on且无可用Hash Join路径时,同样可能硬上嵌套循环

用EXPLAIN/SHOW PLAN快速识别缺失索引的嵌套循环

别猜,直接看执行计划里有没有“Rows远大于Actual Rows”或“Missing Index提示”,以及内表访问类型是不是ALL(MySQL)、Clustered Index Scan(SQL Server)或Seq Scan(PostgreSQL)。

阅读全文