使用子查询加入(派生表)
SELECT x, ...
FROM ( SELECT y, ... FROM ... ) AS a
JOIN tbl ON tbl.x = a.y
WHERE ...
这会将子查询评估为临时表,然后将 JOIN
评估为 tbl
。
在 5.6 之前,临时表上没有索引。所以,这可能非常低效:
SELECT ...
FROM ( SELECT y, ... FROM ... ) AS a
JOIN ( SELECT x, ... FROM ... ) AS b ON b.x = a.y
WHERE ...
使用 5.6,优化器可以计算出最佳索引并在运行中创建它。 (这有一些开销,所以它仍然不是’完美’。)
另一个常见的范例是有一个子查询来初始化一些东西:
SELECT
@n := @n + 1,
...
FROM ( SELECT @n := 0 ) AS initialize
JOIN the_real_table
ORDER BY ...
(注意:这在技术上是一个 CROSS JOIN
(笛卡尔积),如缺少 ON
所示。但它很有效,因为子查询只返回一行必须与 the_real_table
中的 n 行匹配。)