2017-03-07 45 views
-2

我有一个表(我们称之为A)SQL Server 2016中,我想查询。我只需要选择那些具有确定状态的行,所以我需要排除一些行。还有另一个表(B),其中包含来自表A的记录ID和两列col1和col2。如果这些列是非空的,则相应的记录可以被认为是最终的。表A和表B之间存在一对一的关系。由于这些表非常大,我想使用最有效的查询。我应该选择哪一个?哪个是运行此SQL查询最快的方法?

SELECT * 
FROM TableA 
WHERE record_id IN 
    (SELECT record_id FROM TableB WHERE col1 IS NOT NULL AND col2 IS NOT NULL) 

SELECT a.* 
FROM TableA a 
INNER JOIN TableB b ON a.record_id = b.record_id 
WHERE b.col1 IS NOT NULL AND b.col2 IS NOT NULL 

SELECT a.* 
FROM TableA a 
INNER JOIN TableB b 
ON a.record_id = b.record_id 
    AND b.col1 IS NOT NULL 
    AND b.col2 IS NOT NULL 

当然,如果有更快的方式,我没有想到,请分享。我也很想知道为什么一个查询比其他查询更快。

+2

请阅读Eric Lippert的优秀[哪个更快?](https://ericlippert.com/2012/12/17/performance-rant/):“...如果你有两匹马,你想知道哪些二者之间的距离越大,你的马匹的速度越快,不要写简短的马匹描述,在互联网上发布,并要求随机的陌生人猜猜哪个更快......“ –

+2

为什么你不试试它并找到出来吗? –

+0

我做过了,但结果各不相同。差异是相当显着的(〜20%),但更快的查询并不总是一样的... –

回答

0
WITH cte AS 
(SELECT b.record_id, b.col1, b.col2 
FROM TableB b 
WHERE col1 IS NULL 
AND col2 IS NULL --if the field isn't NULL, it might be quicker to do <> '') 

SELECT a.record_id, a.identifyColumnsNeededExplicitely 
FROM cte 
JOIN TableA a ON a.record_id = cte.record_id 
ORDER BY a.record_id 
+0

CTE为什么要在这里提高性能? –

+0

实际上,您可能需要考虑执行此查询FROM tableA而不是FROM cte。这应该使它更快; CTE允许表(已过滤)存储在mem中(最重要的是,只能读取一次),从而使查询更快。下一步,使用执行计划,索引/重新索引无效的表。 – WickedFan

0

在实践中的执行计划将尽一切取决于你的当前索引/聚集索引/外键/约束/统计中的表(又名行数的行/一般containt/...)喜欢。任何分析都应该逐案进行,2个表格的真实情况可能不适用于其他2个表格。

Theorically,

没有任何索引,第一个应该是最好的,因为它将使上操作的优化与表B 1次表扫描,2个contants扫描上表B和表1 1个表扫描。

使用TableA.record_id上的外键引用TableB.record_id或两列中的索引时,第二个应该更快,因为它将使扫描索引和2恒定扫描。

在极少数情况下,它可能是第三种,具体取决于TableB统计信息。但是从数字2开始不远,因为数字3将扫描所有TableB。

在更为罕见的情况下,既不的3

什么我tryng说的是:“既然我们没有没有你的表也不行,打开你的SQL管理,把统计ON和自己尝试一下。“