WHERE
条款有什么好处?
我有一张大桌子,FK到一张小桌子。我可以直接搜索FK,或者我可以加入FK表并在连接表上设置WHERE
限制。什么是更好/更好?
所以这个:
SELECT lt.* FROM LargeTable lt
WHERE lt.SomeId in(12,55)
或者这个:
SELECT lt.* FROM LargeTable lt
INNER JOIN SmallTable st ON lt.SomeId=st.ItemId
WHERE st.Id in(12,55)
我用Set statistics time on
对此进行了测试,但我没想到会出现这种情况。谁能解释一下这里发生了什么?
没有加入的第一次测试:
(946 row(s) affected)
SQL Server Execution Times:
CPU time = 1544 ms, elapsed time = 1580 ms.
使用连接进行第二次测试
(946 row(s) affected)
SQL Server Execution Times:
CPU time = 2636 ms, elapsed time = 366 ms.
编辑:当我执行SELECT Id
而不是SELECT *
时,没有连接的第一个查询的已用时间会更短,执行计划中的查询成本为25%(无连接)和75%对于带有连接的查询。
答案 0 :(得分:4)
根据你的执行计划,两个查询基本上扫描整个大表中的每个记录......第二个查询只是在扫描大表之前从小表中查找一小组记录,这就是为什么相对两者的成本都是50%。
我建议考虑largeTable.SomeId
上的索引,然后使用第一个查询:
SELECT lt.* FROM LargeTable lt
WHERE lt.SomeId in(12,55)
编辑:
所以最大的问题是为什么连接的查询持续时间比没有连接的查询的持续时间短。
我认为马丁史密斯给出了这个问题的答案:
你的第二个获得并行计划,第一个没有
您会注意到您的第一个查询的CPU时间较短,但经过的时间较长。粗略地总结一下,您的第一个查询花费了较少的时间来完成服务器,但是您的第二个查询使用了并行计划,并且使用了多个处理器来执行查询,因此完成所需的时间更少,但总体工作量更大。
答案 1 :(得分:0)
要考虑的两件事:
答案 2 :(得分:0)
因为两个查询都是从提到的大表中提取结果。那么,您对“SomeID”列有 Non clustered Index 吗?
您使用的是此表中的所有列吗?如果不是这样的话。建议仅提及所需的列。
由于这两个查询都是从大表中提取数据所以只能通过“非聚集索引
如果有任何案例只能获得匹配的数据。然后你也可以这样做。
Select ColumnName From
(
Select ColumnName, SomeID from LargeTable Where SomeID in(12,13)
)T
Inner Join SmallTable T1 on T.SomeID = T1.SomeID
如果您想要非常快速的结果。你可以这样做。
Create table #Large
(
Id Int,
ColumnName Varchar(100)
)
Insert into #Large(ID, ColumnNmae)
Select ColumnName, SomeID from LargeTable Where SomeID in(12,13)
最后加入
Select ColumnName From #Large T
Inner Join SmallTable T1 on T.SomeID = T1.SomeID
且没有加入
Select ColumnName from #Large