SQL - 大表和小表之间的内部连接,带有过滤器

时间:2016-08-08 14:50:19

标签: sql-server

我有一个简单的SQL查询,它通过过滤在表A和表B之间进行INNER JOIN。表A非常大,而表B相当小。我只想返回与某个过滤器匹配的行,例如table_B.some_col IN('a','b','c','d')。当然,我将此过滤器作为WHERE子句。但是,建议我复制相同的过滤器,但对于表A并将其放入连接中。例如,

SELECT
*
FROM table_A
INNER JOIN table_B
    ON table_A.pk = table_B.pk
    AND table_A.some_col IN ('a', 'b', 'c', 'd')
WHERE
table_B.some_col IN ('a', 'b', 'c', 'd')

声称这样做可以改进查询计划。不幸的是,由于我的机器的安全限制,我无法检查查询计划。这种说法是真的吗?

1 个答案:

答案 0 :(得分:0)

AndWhere条款中添加过滤器并没有任何区别..

以下是一些测试..

使用的查询..
选择*来自 订单o 加入  hr.employees h  在h.empid = o.empid

过滤和条款..
和empid = 4

执行计划
enter image description here

设置统计信息IO:

Table 'orders'. Scan count 1, logical reads 20, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Employees'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

过滤条款:
其中empid = 4

执行计划:
enter image description here

统计数据IO:

Table 'orders'. Scan count 1, logical reads 20, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Employees'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

在每种情况下,SQLServer足够聪明,可以重新排列查询(因为它是内部联接)并且只获取相关行