MySQL 派生表

作者admin

5月 15, 2025

派生表是 MySQL 查询优化的一种机制,当查询中包含子查询且子查询结果需要进一步处理时,MySQL 会将子查询的结果视为一个临时表,这个临时表就是派生表。

派生表的常见来源

1、JOIN 子查询 这是派生表最常见的场景:

SELECT log.*
FROM main_table log
JOIN (
SELECT id, MAX(date) AS max_date
FROM sub_table
GROUP BY id
) derived_table
ON log.id = derived_table.id;

原因:子查询的结果需要和主表 main_table 进行关联,MySQL 会将子查询的结果存储为一个临时派生表。

2、FROM 子查询 即使没有 JOIN,直接在 FROM 子句中使用子查询,也会生成派生表:

SELECT derived.id, derived.max_date
FROM (
SELECT id, MAX(date) AS max_date
FROM sub_table
GROUP BY id
) derived;

原因:子查询的结果需要作为主查询的输入,所以 MySQL 生成了派生表 derived,并用它作为一个“虚拟表”供主查询使用。

3、UNION 查询 当使用 UNION 将两个结果集合并时,每个分支的结果可能被视为派生表:

SELECT id, name FROM table1
UNION
SELECT id, name FROM table2;

原因:MySQL 会对 table1 和 table2 的查询分别执行,结果存储在临时表中,然后合并两个表的内容。

4、视图(VIEW) 查询视图时,如果视图的定义中包含复杂的子查询或计算,MySQL 可能会将视图内容作为派生表处理:

CREATE VIEW my_view AS
SELECT id, MAX(date) AS max_date
FROM sub_table
GROUP BY id;

SELECT * FROM my_view WHERE max_date > ‘2024-01-01’;

5、CTE(公共表表达式,WITH 子句,MySQL 8.0+) 使用 WITH 定义的临时结果集,也可能被当作派生表处理:

WITH temp AS (
SELECT id, MAX(date) AS max_date
FROM sub_table
GROUP BY id
)
SELECT *
FROM temp
WHERE max_date > ‘2024-01-01’;

原因:WITH 的定义等同于一个子查询,MySQL 会将其作为临时派生表处理。

派生表的作用与影响

 

作用

  • 将复杂查询分解为更简单的部分。
  • 为主查询提供一个固定的“中间结果”。
  • 避免重复计算(尤其是子查询中含有聚合操作时)。

影响

  • 如果派生表的结果集较大,可能占用大量内存或磁盘空间。
  • 没有索引的派生表在主查询中被访问时,查询性能可能降低。

如何减少派生表的使用

如果发现派生表影响性能,可以通过以下方法优化:

1、避免不必要的子查询 将子查询逻辑合并到主查询中,例如通过窗口函数替代子查询:

SELECT id, date
FROM (
SELECT id, date, ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS rn
FROM sub_table
) temp
WHERE rn = 1;

2、使用索引优化派生表的访问 确保派生表中关键字段有合适的索引,减少主查询匹配的代价。

3、使用临时表替代派生表 对于复杂查询,可以将子查询结果存储到显式的临时表中:

CREATE TEMPORARY TABLE temp AS
SELECT id, MAX(date) AS max_date
FROM sub_table
GROUP BY id;

SELECT *
FROM temp
WHERE max_date > ‘2024-01-01’;

 

 

作者 admin

百度广告效果展示