以下代码段应该执行相同的工作。
SELECT t1.* FROM table1 t1
INNER JOIN table2 t2
ON t1.ID = t2.IDService
WHERE t2.Code = @code
和
SELECT * FROM table1 t1
WHERE t1.ID IN (SELECT IDService FROM table2 WHERE Code = @code)
一般来说哪一个是最好的解决方案?而在计算上,最好有两个嵌套选择还是更好用内连接?
修改
考虑到table1的PK为ID
,而table2的PK为该对(IDService,Code
)。因此,修复代码(使用WHERE
子句)并将ON
子句应用于IDService,我可以假设每个选择的结果都是相同的。
答案 0 :(得分:0)
作为一般规则, JOIN 几乎总是比 SUB-QUERY 表现更好,但有例外情况。
如果要使用子查询, EXIST 子句,对于大多数用例,通常比 IN 表现更好。
对于测试用例,您可以查看此site
你应该遵循以下规则......
如果您需要来自多个表的数据,那么您可以随时加入。
如果需要多个查询,并且每个子查询都提供查询中涉及的表的子集,则可以使用子查询。
如果查询需要NOT EXISTS条件,则必须使用子查询,因为NOT EXISTS仅在子查询中运行;同样的原则适用于EXISTS条件。
程序SQL查询优化器将一些子查询更改为连接,通常更有效地处理连接。
答案 1 :(得分:0)
你认为他们应该做同样的工作是不正确的。想象一下这组测试数据:
<强> T1 强>
ID
----
1
2
3
4
5
<强> T2 强>
ID
---
1
1
1
2
2
3
<强> DDL 强>
CREATE TABLE dbo.T1 (ID INT NOT NULL);
INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
CREATE TABLE dbo.T2 (ID INT NOT NULL);
INSERT dbo.T2 (ID) VALUES (1), (1), (1), (2), (2), (3);
SELECT *
FROM dbo.T1
WHERE T1.ID IN (SELECT T2.ID FROM dbo.T2);
SELECT T1.*
FROM dbo.T1
INNER JOIN dbo.T2
ON T1.ID = T2.ID;
<强>结果
ID
---
1
2
3
ID
---
1
1
1
2
2
3
如果您要搜索的列是唯一的,则结果仅相同。
CREATE TABLE dbo.T1 (ID INT NOT NULL);
INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
CREATE TABLE dbo.T2 (ID INT NOT NULL);
INSERT dbo.T2 (ID) VALUES (1), (2), (3);
SELECT *
FROM dbo.T1
WHERE T1.ID IN (SELECT T2.ID FROM dbo.T2);
SELECT T1.*
FROM dbo.T1
INNER JOIN dbo.T2
ON T1.ID = T2.ID;
即使结果相同,执行计划也不是。使用IN
的第一个查询能够使用反半连接,这意味着它知道不需要t2中的数据,所以一旦找到单个匹配,它就会停止扫描以进一步匹配。
如果您将第二个表限制为仅包含唯一值,那么您将看到相同的计划:
CREATE TABLE dbo.T1 (ID INT NOT NULL PRIMARY KEY);
INSERT dbo.T1 (ID) VALUES (1), (2), (3), (4), (5);
CREATE TABLE dbo.T2 (ID INT NOT NULL PRIMARY KEY);
INSERT dbo.T2 (ID) VALUES (1), (2), (3);
SELECT *
FROM dbo.T1
WHERE T1.ID IN (SELECT T2.ID FROM dbo.T2);
SELECT T1.*
FROM dbo.T1
INNER JOIN dbo.T2
ON T1.ID = T2.ID;
总之,这两个查询不会总是产生相同的结果,并且它们并不总是具有相同的计划。这实际上取决于您的索引和数据/查询的宽度。