Documentation Home

8.2.2.4 优化派生表

优化器按如下方式处理派生表:

  • 优化器推迟派生表的具体化,直到在查询执行期间需要它们的内容,这提高了性能。

  • 对于非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;

优化器构建一个列索引 f1derived_t2如果这样做将允许使用 ref最低成本执行计划的访问。添加索引后,优化器可以将物化派生表视为具有索引的常规表,并且从生成的索引中获得类似的好处。与没有索引的查询执行成本相比,创建索引的开销可以忽略不计。如果 ref访问会导致比其他访问方法更高的成本,则优化器不会创建索引并且不会丢失任何内容。

对于优化器跟踪输出,合并的派生表或视图引用未显示为节点。只有它的基础表出现在顶级查询的计划中。