过滤或加入是否先在T-SQL中发生?

时间:2009-06-15 11:47:03

标签: tsql

我有两张桌子:

Customers(Id, Name, TownId) T
Towns(Id, Name)

我有一个这样的SQL语句:

SELECT *
FROM Customers
INNER JOIN Towns ON Towns.Id = Customers.TownId
WHERE Customers.Id > 5

首先会发生什么? 它会过滤Customers表,然后用Towns表加入所选记录吗?
是否会将所有Customers加入Towns,然后过滤?还是你说不出来?

4 个答案:

答案 0 :(得分:16)

优化器会做任何它认为最快的事情。

您可以使用联接提示强制某些行为,或者使用统计信息和索引来鼓励某些行为。但是,通常最好信任优化器。

如果您想详细解释查询的执行方式,请查看execution plan

答案 1 :(得分:1)

一般来说,加入首先发生。考虑:

t1.id  t1.foo      t2.id   t2.bar  t2.t1_id
-------------      ------------------------
    1   'abc'          1    '123'         1
    2   'def'          2    '456'         1
    3   'ghi'          3    '789'         2
    4   'jkl'          4    '0'        NULL

此查询:

SELECT
  t1.foo,
  t2.bar
FROM
  t1
  LEFT JOIN t2 ON t1.id = t2.t1_id
WHERE
  t2.somevalue IS NOT NULL

将产生:

foo     bar
-------------
'abc'   '123'
'abc'   '456'
'def'   '789'

然而,当您将过滤器拉入连接条件时,也会在连接处进行过滤:

SELECT
  t1.foo,
  t2.bar
FROM
  t1
  LEFT JOIN t2 ON t1.id = t2.t1_id AND t2.somevalue IS NOT NULL

将产生:

foo     bar
-------------
'abc'   '123'
'abc'   '456'
'def'   '789'
'ghi'    NULL
'jkl'    NULL

查询越复杂,就越不容易说出在加入表之前哪些记录被执行计划过滤掉,以及之后的哪些记录。

答案 2 :(得分:0)

在外行术语中,过滤器将在连接之前发生,因此在过滤之前不会加入两个表的整体。

根据您使用的工具集,您应该找到一个选项来显示查询的执行计划,这将有助于您查看执行顺序和每个阶段的成本。

答案 3 :(得分:0)

当查询作为合并连接执行时,过滤和连接同时发生。