举个例子,我想获取应用了某些标签的所有项目的列表。我可以执行以下任一操作:
SELECT Item.ID, Item.Name
FROM Item
WHERE Item.ID IN (
SELECT ItemTag.ItemID
FROM ItemTag
WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55)
或者
SELECT Item.ID, Item.Name
FROM Item
LEFT JOIN ItemTag ON ItemTag.ItemID = Item.ID
WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55
GROUP BY Item.ID, Item.Name
或者完全不同的东西。
一般来说(假设有一般规则),什么是更有效的方法?
最佳答案
SELECT Item.ID, Item.Name FROM Item WHERE Item.ID IN ( SELECT ItemTag.ItemID FROM ItemTag WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55)
or
SELECT Item.ID, Item.Name FROM Item LEFT JOIN ItemTag ON ItemTag.ItemID = Item.ID WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55 GROUP BY Item.ID
您的第二个查询将无法编译,因为它引用 Item.Name
且未对其进行分组或聚合。
如果我们从查询中删除GROUP BY
:
SELECT Item.ID, Item.Name
FROM Item
JOIN ItemTag
ON ItemTag.ItemID = Item.ID
WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55
这些仍然是不同的查询,除非 ItemTag.ItemId
是 UNIQUE
键并如此标记。
SQL Server
能够检测 UNIQUE
列上的 IN
条件,并且只会转换 IN
> 条件转换为 JOIN
。
如果ItemTag.ItemID
不是UNIQUE
,则第一个查询将使用一种SEMI JOIN
算法,该算法在以下方面非常有效SQL Server
。
您可以将第二个查询转换为JOIN
:
SELECT Item.ID, Item.Name
FROM Item
JOIN (
SELECT DISTINCT ItemID
FROMT ItemTag
WHERE ItemTag.TagID = 57 OR ItemTag.TagID = 55
) tags
ON tags.ItemID = Item.ID
但是这个比 IN
或 EXISTS
效率稍低。
请参阅我博客中的这篇文章,了解更详细的性能比较:
关于sql-server - SQL 效率 : WHERE IN Subquery vs. JOIN then GROUP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1179231/