先过滤后加入还是先加入后过滤?

Hik*_*ari 6 sql-server optimization sql-server-2012

考虑 5 个表,每个表都有超过 10 亿条记录。

一个查询需要加入它们。而且我知道他们需要的记录不到 10%。假设它们都有一个日期维度,并且只需要当月的数据。

什么应该更快:

1)使用简单的SELECT:连接所有表,然后过滤(WHERE)当月每个表的维度。

2)创建5个临时表,过滤每个源表为当月记录,这里我们也可以趁机只选择需要的列,然后加入这些临时表。

额外的可能性:

3) 维护二级表,只有当前月/年的数据。这些表由提供主要表的相同 ETL 维护。

pap*_*zzo 6

建立查询并查看。
查询优化器通常足够聪明,可以提前过滤。
SQL 是合乎逻辑的 - 在 where 中并不意味着它将最后处理。

很明显,您需要连接和过滤器的索引。

当您达到 5 个或更多连接时,优化器通常会变得防御并进入循环连接。
我有引文吗 - 没有。这是一个观察。

当达到 5 个或更多时,将条件拉入连接可以帮助优化器。
我有引文吗 - 没有。这是一个观察。

select * 
from tableA 
join tableB  
      on tableA.fkB = tableB.id 
     and tableA.date1 >= @date1start   
     and tableA.date1 <  @date1end 
join tableC  
      on tableA.fkC = tableC.id 
     and tableC.filter1 = 'do me early'  
Run Code Online (Sandbox Code Playgroud)

一次建立一个连接,看看它什么时候变得愚蠢。
一次优化一个连接。

如果您要实现,请在#temp 上放一个 pk。
从你认为你会得到最大冲击的地方开始。

where / join 中的 OR 条件是最麻烦的,通常会导致循环连接。
这些应该是第一个实现的。

您可以强制散列连接,但这是一个滑坡,可能会变坏。

所有表都有日期维度似乎有点奇怪,您通常会有一些具有更多静态类型数据的查找类型表。

如果您不需要表中的输出,那么 where exists可能会更好地执行。