这是我的示例查询
Select table1.id
from table1
where table.id in (select table2.id
from table2
where table2.id in (select table3.id
from table3)
)
order by table1.id
limit 100检查上述查询的优化器跟踪。优化跟踪成本
由于复制-WEEDOUT成本较低,mysql对上述查询采用了复制-WEEDOUT策略.
似乎join_optimization的一切都是好的。但是最后,在检查了join_execution部分之后。复制-WEEDOUT通常创建临时表。但是在这里,由于堆大小不足以处理临时表,所以继续创建ondisk表(Converting_tmp_table_to_ondisk)。
由于磁盘临时表,我的查询执行速度变慢了。
这里发生了什么?
优化器跟踪不计算连接优化部分中磁盘表的成本。如果计算了磁盘表成本,则它将高于第一次匹配。那么final_semijoin_strategy将是第一匹配策略,这样我的查询就会更快。
有没有方法MYSQL计算连接优化部件本身中的磁盘表的成本,或者针对这个特定问题进行任何其他工作?
MYSQ-5.7,INNODB
注意:这是一个非常动态的查询,其中多个条件将根据查询中的请求添加。因此,我已经以所有可能的方式优化了查询。最后解决了这个磁盘成本问题。请避免优化查询(比如更改查询结构,强制执行第一匹配策略)。为了增加堆的大小(我对它不太确定,在不同的论坛上,许多人说它可能在其他查询中带来不同的问题)
发布于 2020-12-15 20:09:42
众所周知,IN( SELECT ... )效率低下。尽量避免。
如所示,查询可能等同于
SELECT t1.id
FROM t1
JOIN t2 USING(id)
JOIN t3 USING(id)
ORDER BY id
LIMIT 100这将很好地优化。
这个公式不需要构建任何临时表,更不必构建一个基于磁盘的表。
https://stackoverflow.com/questions/65276645
复制相似问题