我有两张桌子:
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
,然后过滤?还是你说不出来?
答案 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)
当查询作为合并连接执行时,过滤和连接同时发生。