为什么SQL非相关子查询执行计划只缓存一次,其执行结果如何被重用?

2026-04-27 17:351阅读0评论SEO基础
  • 内容介绍
  • 相关推荐

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

为什么SQL非相关子查询执行计划只缓存一次,其执行结果如何被重用?

非相关子查询仅执行一次,并非语法规定,而是优化器主动进行的省事动作——它识别出子查询不依赖于外部数据,便将其结果一次性计算出,存储在内存中的常量区域或临时物化表中,后续重复使用。

怎么快速判断一个子查询是不是非相关的

核心就一条:子查询里有没有出现外层表的列名(比如 t1.idorders.user_id)。

  • 没有——就是非相关,例如 (SELECT MAX(price) FROM products)(SELECT value FROM config WHERE key = 'timeout')
  • 有——就是相关,例如 (SELECT COUNT(*) FROM logs WHERE user_id = users.id),哪怕只多写了一个点号,也会触发逐行重算
  • 验证方法:把子查询整段复制出来,单独 SELECT 一把,能跑通且不报“Unknown column”就是非相关

EXPLAIN 里怎么看它到底执行了几次

不能只看 select_typeSUBQUERY 还是 DEPENDENT SUBQUERY,得结合执行计划结构来确认实际行为。

阅读全文

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

为什么SQL非相关子查询执行计划只缓存一次,其执行结果如何被重用?

非相关子查询仅执行一次,并非语法规定,而是优化器主动进行的省事动作——它识别出子查询不依赖于外部数据,便将其结果一次性计算出,存储在内存中的常量区域或临时物化表中,后续重复使用。

怎么快速判断一个子查询是不是非相关的

核心就一条:子查询里有没有出现外层表的列名(比如 t1.idorders.user_id)。

  • 没有——就是非相关,例如 (SELECT MAX(price) FROM products)(SELECT value FROM config WHERE key = 'timeout')
  • 有——就是相关,例如 (SELECT COUNT(*) FROM logs WHERE user_id = users.id),哪怕只多写了一个点号,也会触发逐行重算
  • 验证方法:把子查询整段复制出来,单独 SELECT 一把,能跑通且不报“Unknown column”就是非相关

EXPLAIN 里怎么看它到底执行了几次

不能只看 select_typeSUBQUERY 还是 DEPENDENT SUBQUERY,得结合执行计划结构来确认实际行为。

阅读全文