优化器按如下方式处理派生表:
优化器推迟派生表的具体化,直到在查询执行期间需要它们的内容,这提高了性能。
对于非
EXPLAIN
查询,物化的延迟可能导致根本不必这样做。考虑一个将派生表的结果连接到另一个表的查询:如果优化器首先处理另一个表并发现它没有返回任何行,则不需要进一步执行连接并且优化器可以完全跳过具体化派生表。在查询执行期间,优化器可能会向派生表添加索引以加速从中检索行。
对于包含派生表的查询,
请考虑以下EXPLAIN
语句:SELECT
EXPLAIN SELECT * FROM (SELECT * FROM t1) AS derived_t1;
优化器通过延迟派生表直到
SELECT
执行期间需要结果来避免具体化派生表。在这种情况下,不会执行查询(因为它出现在
EXPLAIN
语句中),因此永远不需要结果。
即使对于已执行的查询,派生表具体化的延迟也可能使优化器能够完全避免具体化。考虑以下查询,它将派生表的结果连接到另一个表:
SELECT *
FROM t1 JOIN (SELECT t2.f1 FROM t2) AS derived_t2
ON t1.f2=derived_t2.f1
WHERE t1.f1 > 0;
如果优化t1
首先处理并且WHERE
子句产生空结果,则连接必须为空并且派生表不需要具体化。
对于派生表需要物化的情况,优化器可能会向物化表添加索引以加快对其的访问。如果这样的索引允许
ref
访问表,它可以大大减少查询执行期间读取的数据量。考虑以下查询:
SELECT *
FROM t1 JOIN (SELECT DISTINCT f1 FROM t2) AS derived_t2
ON t1.f1=derived_t2.f1;
优化器构建一个列索引
f1
,derived_t2
如果这样做将允许使用
ref
最低成本执行计划的访问。添加索引后,优化器可以将物化派生表视为具有索引的常规表,并且从生成的索引中获得类似的好处。与没有索引的查询执行成本相比,创建索引的开销可以忽略不计。如果
ref
访问会导致比其他访问方法更高的成本,则优化器不会创建索引并且不会丢失任何内容。
对于优化器跟踪输出,合并的派生表或视图引用未显示为节点。只有它的基础表出现在顶级查询的计划中。