Mysql 澄清创建临时表的联接顺序
我在mysql中有一个大型查询,涉及将多个表连接在一起。它太慢了,所以我已经做了“解释”,看到它正在创建一个临时表,我怀疑它占用了大部分执行时间。我发现了一些相关信息:Mysql 澄清创建临时表的联接顺序,mysql,join,optimization,explain,Mysql,Join,Optimization,Explain,我在mysql中有一个大型查询,涉及将多个表连接在一起。它太慢了,所以我已经做了“解释”,看到它正在创建一个临时表,我怀疑它占用了大部分执行时间。我发现了一些相关信息: 描述可能创建临时表的条件。(“服务器在以下情况下创建临时表…”[强调添加]) 这是一个相关的SO问题,它提供了指向文档的链接,并将其应用于特定案例 这是一个相关的问题,讨论了连接的求值顺序 按照我编写联接的顺序,我的查询似乎不符合文档1中列出的任何条件。但是,通过实验,我发现如果删除我的orderby子句,就不会创建临时表。这让
orderby
子句,就不会创建临时表。这让我从文件中看到了这条规则:
对包含ORDER BY子句和其他GROUP BY子句的语句的求值,或对ORDER BY或GROUP BY包含联接队列中第一个表以外的表中的列的语句的求值
这与上面#2中的示例中所使用的规则相同,但在#2中,OP在子句中显式地具有来自多个表的列,因此这至少在表面上是不同的
此外,当我查看explain
的输出时,优化器似乎没有首先使用我首先列出的表。放下一个伪查询,例如:
select * from A
join B on A.c1=B.c1
join C on A.c2=C.c2
where A.c3='value'
order by A.c4
我想说,我的orderby
子句根据我编写查询的顺序,只使用“连接队列中的第一个表”中的列。另一方面,explain
的输出表明它首先考虑表B,然后考虑表A
以下是问题:
select * from A
join B on A.c1=B.c1
join C on A.c2=C.c2
where A.c3='value'
order by A.c4
- 优化器将使用各种启发式方法来决定查看表的顺序。在这种情况下,由于过滤器(
)的原因,它将以WHERE…
开头A
上的这个“复合”索引应该消除A
的tmp&filesort:ORDER BY
。不,这与索引(c3)、索引(c4)不同索引(c3,c4)
- 从
获取行后,可以将A
或B
放入(“嵌套循环联接”)。这些索引很重要:C
:B
和(c1)
:C
(c2)
和直联
通常是个坏主意,只能作为最后手段使用。这可能有助于今天的质疑,但对明天不利力指数
提供了更多信息,有时甚至指出需要两个tmp表EXPLAIN FORMAT=JSON SELECT…
更多提示:谢谢,但这与具体的(大大简化的)示例联系太紧密,没有多大帮助。我问的问题比这个更一般。这个一般性主题的问题是有太多的变体。如果你把
A.c4
改为B.c4
,我说的大部分都是“错的”。我的食谱尽我所能地用“一般”语句来描述。@Brick-在重读你的问题时,我能想到十几个“如果查询有……那么……如果……那么……其他……”。没有足够的空间来解释它们。相关子查询,不相关子查询,左,按x顺序按y分组,按a.x顺序按b.y分组,其中a.x=。。b.y=..,SELECT*vs SELECT short list,缺少索引,额外索引等等--所有这些都会导致异常。