题
我有一个查询,看起来像这样:
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
....
此select返回一行。在嵌入使用,选择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
s是潜在的危险,但对于这样的,其中初始SELECT
确实是高度选择性的情况下,它可以是非常有效的。任何人都可以摆脱任何这光?
修改作为反馈感谢为止。我担心的是不是这么多的行由行性质的在线查询,而是,它似乎无法面对的变量,而不是(下同)硬编码值使用主键索引的事实。我的猜测是,如果分析有没有被最近运行的,则优化假定它必须做一个表扫描,因为它没有对数据分布的知识。但不应该的事实范围查找是在主键做不能补偿是什么?
解决方案
如果相关子没有被优化井,然后尝试此查询:
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。他们提高每一个版本的优化,所以你可能有一个较新的版本得到更好的结果。
其他提示
尝试通过使用JOIN如果可以,以避免相关子查询。
观看的YouTube 对MySQL的性能这个伟大的视频。转到31:00分钟。扬声器周杰伦管道会谈有关避免相关的子查询。
如果从包含它的查询的子查询的引用的字段,子查询必须被在包含查询每每一行重新运行,因为引用的字段可以是在每行中不同。如果它是完全自包含的,它可以外部查询开始处理之前运行一次。