此查询运行超过 12 秒,即使所有表都相对较小 - 大约 2000 行。
SELECT attr_73206_ AS attr_73270_
FROM object_73130_ f1
LEFT OUTER JOIN (
SELECT id_field, attr_73206_ FROM (
SELECT m.id_field, t0.attr_73102_ AS attr_73206_ FROM object_73200_ o
INNER JOIN master_slave m ON (m.id_object = 73130 OR m.id_object = 73290) AND (m.id_master = 73200 OR m.id_master = 73354) AND m.id_slave_field = o.id
INNER JOIN object_73101_ t0 ON t0.id = o.attr_73206_
ORDER BY o.id_order
) AS o GROUP BY o.id_field
) AS o ON f1.id = o.id_field
两个表都有字段id
作为主键。此外,、id_field
和中的所有字段都已编入索引。至于这个查询的逻辑,总体上是主从式的。表是主表,表是明细表。它们由一个表链接。是一个临时表,用于通过其 id 获取字段的实际值。对于主表中的每一行,查询从其详细表的第一行返回一个字段。首先,查询有另一种外观,但在stackoverflow,我被建议使用这种更优化的结构(而不是以前使用的子查询,顺便说一下,查询开始运行得更快)。我观察到第一个子查询id_order
attr_73206_
master_slave
object_73130_
object_73200_
master_slave
object_73101_
attr_73206_
JOIN
block 运行速度非常快,但返回的行数与主主表中的行数相当。无论如何,我不知道如何优化它。我只是想知道为什么一个简单的快速运行的连接会引起这么多麻烦。哦,主要的观察结果是,如果我object_73101_
从查询中删除一个 ad-hoc,只返回一个 id,而不是一个真实的值,那么查询运行得很快。所以,所有的注意力都应该集中在查询的这一部分
INNER JOIN object_73101_ t0 ON t0.id = o.attr_73206_
为什么它会如此严重地减慢整个查询的速度?
编辑
通过这种方式,它运行超快
SELECT t0.attr_73102_ AS attr_73270_
FROM object_73130_ f1
LEFT OUTER JOIN (
SELECT id_field, attr_73206_ FROM (
SELECT m.id_field, attr_73206_ FROM object_73200_ o
INNER JOIN master_slave m ON (m.id_object = 73130 OR m.id_object = 73290) AND (m.id_master = 73200 OR m.id_master = 73354) AND m.id_slave_field = o.id
ORDER BY o.id_order
) AS o GROUP BY o.id_field
) AS o ON f1.id = o.id_field
LEFT JOIN object_73101_ t0 ON t0.id = o.attr_73206_
因此,您可以看到,我只是将临时连接放在子查询之外。但是,问题是,子查询是自动创建的,我可以访问创建它的算法部分,我可以修改这个算法,但我无权访问构建整个查询的算法部分,所以我唯一能做的就是以某种方式修复子查询。无论如何,我仍然不明白为什么INNER JOIN
在子查询中可以使整个查询减慢数百倍。
编辑
一个新版本的查询,每个表都有不同的别名。这对性能没有影响:
SELECT attr_73206_ AS attr_73270_
FROM object_73130_ f1
LEFT OUTER JOIN (
SELECT id_field, attr_73206_ FROM (
SELECT m.id_field, t0.attr_73102_ AS attr_73206_ FROM object_73200_ a
INNER JOIN master_slave m ON (m.id_object = 73130 OR m.id_object = 73290) AND (m.id_master = 73200 OR m.id_master = 73354) AND m.id_slave_field = a.id
INNER JOIN object_73101_ t0 ON t0.id = a.attr_73206_
ORDER BY a.id_order
) AS b GROUP BY b.id_field
) AS c ON f1.id = c.id_field
编辑
这是EXPLAIN
命令的结果:
| id | select_type | TABLE | TYPE | possible_keys | KEY | key_len | ROWS | Extra |
| 1 | PRIMARY | f1 | INDEX | NULL | PRIMARY | 4 | 1570 | USING INDEX
| 1 | PRIMARY | derived2| ALL | NULL | NULL | NULL | 1564 |
| 2 | DERIVED | derived3| ALL | NULL | NULL | NULL | 1575 | USING TEMPORARY; USING filesort
| 3 | DERIVED | m | RANGE | id_object,id_master,..| id_object | 4 | 1356 | USING WHERE; USING TEMPORARY; USING filesort
| 3 | DERIVED | a | eq_ref | PRIMARY,attr_73206_ | PRIMARY | 4 | 1 |
| 3 | DERIVED | t0 | eq_ref | PRIMARY | PRIMARY | 4 | 1 |
那有什么问题?
编辑
这是EXPLAIN
“超快”查询的命令结果
| id | select_type | TABLE | TYPE | possible_keys | KEY | key_len | ROWS | Extra
| 1 | PRIMARY | f1 | INDEX | NULL | PRIMARY | 4 | 1570 | USING INDEX
| 1 | PRIMARY | derived2| ALL | NULL | NULL | NULL | 1570 |
| 1 | PRIMARY | t0 | eq_ref| PRIMARY | PRIMARY | 4 | 1 |
| 2 | DERIVED | derived3| ALL | NULL | NULL | NULL | 1581 | USING TEMPORARY; USING filesort
| 3 | DERIVED | m | RANGE | id_object,id_master,| id_bject | 4 | 1356 | USING WHERE; USING TEMPORARY; USING filesort
| 3 | DERIVED | a | eq_ref | PRIMARY | PRIMARY | 4 | 1 |
关闭
我将使用上面介绍的我自己的“超快速”查询。我认为不可能再优化它了。