我重构了一个从另一家公司继承的应用程序的缓慢部分,以使用内部连接而不是子查询
WHERE id IN (SELECT id FROM ...)
重构的查询运行速度提高了约100倍.(约50秒到约0.3)我预计会有所改善,但任何人都可以解释为什么它如此激烈?where子句中使用的列都已编入索引.SQL是否每行执行一次where子句中的查询?
更新 - 解释结果:
不同之处在于"where in in()"查询的第二部分 -
2 DEPENDENT SUBQUERY submission_tags ref st_tag_id st_tag_id 4 const 2966 Using where
vs 1带连接的索引行:
SIMPLE s eq_ref PRIMARY PRIMARY 4 newsladder_production.st.submission_id 1 Using index
Jeffrey L Wh.. 159
"相关子查询"(即,where条件依赖于从包含查询的行获得的值的那个)将对每一行执行一次.非相关子查询(where条件独立于包含查询的子查询)将在开头执行一次.SQL引擎自动进行区分.
但是,是的,解释计划会给你肮脏的细节.
"相关子查询"(即,where条件依赖于从包含查询的行获得的值的那个)将对每一行执行一次.非相关子查询(where条件独立于包含查询的子查询)将在开头执行一次.SQL引擎自动进行区分.
但是,是的,解释计划会给你肮脏的细节.
您正在为每一行运行子查询一次,而连接发生在索引上.
这是一个如何在MySQL 6.0中评估子查询的示例.
新的优化器会将这种子查询转换为连接.
对每个版本运行解释计划,它会告诉您原因.
在针对数据集运行查询之前,优化器会尝试以这样的方式组织查询,即它可以尽可能快地从结果集中删除尽可能多的元组(行).通常当您使用子查询(尤其是坏查询)时,在外部查询开始运行之前,无法从结果集中删除元组.
没有看到查询很难说原始的那么糟糕,但我的猜测是优化器无法做得更好.运行'explain'将显示用于检索数据的优化器方法.