首页 > 解决方案 > 在任何数据库查询中总是有一个“基表”吗?

问题描述

好的,这只是理论上的,所以如果一个公正的数据库爱好者发表意见,那就太好了。

为了争论,让我们同意对于查询有“基表”这样的概念,其中一个表驱动结果集的大部分信息。想象一个查询,其中存在三个关系 - TableA、TableB 和 TableC

假设 TableA 有 100 万条记录,TableC 有 500 条记录,TableC 有 10,000 条记录。

假设查询是这样的 -

SELECT A.Col1
     , A.Col2
     , A.Col3
     , A.Col4
     , A.Col5
FROM TableA A
 LEFT JOIN TableB B ON B.ID = A.TableBID
 LEFT JOIN TableC C ON C.ID = A.TableCID

好的,显然TableA 是上面的基本关系。它是最大的表,它通过“从”连接来驱动结果集,从视觉上看,列甚至在结果集的“左侧”。(左边的东西实际上是我同事的标准)。

现在,假设 TableA 再次有 100 万行,TableB 是“连接”或“桥”表,有 500,000 行,TableC 有 1,000,000 行。因此,假设查询只是一个外连接,用于获取 TableA 和 TableC 中存在如下关系的所有列......

SELECT A.*
     , C.*
FROM TableC C
 FULL OUTER JOIN TableB B ON C.ID = B.TableAID
 FULL OUTER JOIN TableA A ON A.ID = B.TableCID

好的,鉴于最后一个查询,谁能告诉我“基本关系”是什么?我不认为有一个,但希望另一个数据库人的意见。

标签: sqldatabaserelational-databaserdbmsdatabase-theory

解决方案


术语“基表”有一个定义,它与您所描述的无关。“基表”几乎只是一个“表”。也就是说,它不是视图,也不是表值函数,也不是查询的结果。它作为显式表存储在数据库中。

您似乎正在掌握的内容似乎与优化策略更相关。我在优化的上下文中使用了类似的术语来描述优化器正在访问的“驱动表”。这样做的目的是区分不同的执行计划。

考虑以下查询:

from t1 join t2 using (col)

有多种不同的执行计划。以下是一些方法以及可能被认为是它们的“驱动表”(如果有的话):

for each row in t1
    for each row in t2
         compare col
-->  t1 is the "driving table"

for each row in t2
    for each row in t1
        compare col
--> t2 is the "driving table"

for each row in t1
    look up t2 value using index on t2(col)
--> t1 is the "driving table"

sort t1 by col
sort t2 by col
compare the rows in the two sorted sets
--> no "driving table"

hash t1 by col
hash t2 by col
compare the hash maps
--> no "driving table"

换句话说,“驱动”表与查询结构关系不大。它基于用于查询的优化策略。也就是说,left joins 和right joins 限制了优化路径。因此,在嵌套循环或索引查找情况下,“第一个”(或“最后一个”)表将是驱动表。


推荐阅读