我有一个看起来像这样的查询:
select
id
, int1
, int2
, (select count(*) from big_table_with_millions_of_rows
where id between t.int1 and t.int2)
from myTable t
where
....
此选择只返回一行.内联选择中使用的id是索引列(主键).如果我将t.int1和t.int2替换为此单行返回的int1 / int2的值,则查询以毫秒为单位完成.如果我执行上面的查询 – 即引用int1 / int2,大约需要10分钟.当我运行探查器并查看实际发生的情况时,我发现99%的时间引擎忙于从内联查询返回数据.看起来MySql实际上正在运行
select ... from big_table_with_millions_of_rows
在应用之前一次内联查询
where id between t.int1 and t.int2
咬一下结果.这可能是真的吗?如果没有,那么发生了什么?我一直认为内联SELECT有潜在危险,因为它们作为查询的最后一个元素逐行执行,但对于这样的情况,初始SELECT确实具有高选择性,它可以非常高效.任何人都可以对此有所了解吗?
编辑:感谢目前为止的反馈.我关心的不是内联查询的逐行性质,而是面对变量而不是(相同的)硬编码值时似乎无法使用主键索引的事实.我的猜测是,如果最近没有运行ANALYZE,那么优化器会假设它必须进行表扫描,因为它不知道数据分布.但是不应该在主键上完成范围查找这一事实不能弥补这一点吗?
最佳答案 如果相关子查询未得到很好的优化,请尝试以下查询:
select
t.id
, t.int1
, t.int2
, count(*)
from myTable t
left outer join big_table_with_millions_of_rows b
on (b.id between t.int1 and t.int2)
where
....
group by t.id
这应该更好地优化.
更新你的更新问题:对,MySQL在优化方面不是市场上最复杂的RDBMS.当MySQL无法优化像这样的角落情况时,不要感到惊讶.
我是MySQL的粉丝,因为它的易用性和开源以及所有这些好东西,但事实是它的竞争对手在技术方面远远领先于MySQL.每个RDBMS都有一些“盲点”,但MySQL看起来更大.
还要确保您使用的是最新版本的MySQL.它们改进了每个版本中的优化器,因此使用较新版本可能会获得更好的结果.