我有一个查询,看起来像这样:

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.int1t.int2与此单行返回INT1 / INT2的值,查询完成以毫秒为单位。如果我执行与上述查询 - 与引用即到INT1 / INT2,大约需要10分钟。当我运行探查器,看看到底发生了什么,我看到的引擎正忙于从联查询返回的数据99%的时间。看起来好像是mysql的实际运行

select ... from big_table_with_millions_of_rows 

内联的查询位一旦施加前的

where id between t.int1 and t.int2

位的结果。可这是真的吗?如果不是,那么究竟是怎么回事?我一直认为,因为他们执行的行由行作为查询的最后一个元素内嵌SELECTs是潜在的危险,但对于这样的,其中初始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分钟。扬声器周杰伦管道会谈有关避免相关的子查询。

如果从包含它的查询的子查询的引用的字段,子查询必须被在包含查询每每一行重新运行,因为引用的字段可以是在每行中不同。如果它是完全自包含的,它可以外部查询开始处理之前运行一次。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top