1

以下两个 SQL 查询返回相同的结果:

    SELECT * FROM Table1
    WHERE Table1.Value1 = 'something' OR Table1.Value2 IN (SELECT Value2 FROM Table2)

    SELECT * FROM Table1
    LEFT JOIN Table2 
    ON Table1.Value2 = Table2.Value2
    WHERE (Table1.Value1 = 'something' OR Table2.Value2 IS NOT NULL)

同样,这两个查询返回相同的结果:

    SELECT * FROM Table1
    WHERE Table1.Value1 = 'something' AND Table1.Value2 NOT IN (SELECT Value2 FROM Table2)

    SELECT * FROM Table1
    LEFT JOIN Table2
    ON Table1.Value2 = Table2.Value2
    WHERE Table1.Value1 = 'something' AND Table2.Value2 IS NULL

就个人而言,我发现使用“IN”或“NOT IN”的选项更容易阅读(特别是因为我的实际查询中已经有一堆连接)。但是,如果 Table2 中的值越来越多(目前只返回三个结果),这个查询会不会变得低效?或者查询优化器会在幕后把它找出来并把它变成一个连接吗?我正在使用 SQL Server 2012。

4

2 回答 2

1

第一个会更好:

SELECT <cols> 
  FROM dbo.Table1
  WHERE Value1 = 'something' 
  OR EXISTS (SELECT 1 FROM dbo.Table2 WHERE Value2 = Table1.Value2);

尽管您的性能问题 - 假设 Value2 在两个位置都被索引并且您实际上只选择您需要的列而不是使用 * 强制扫描或查找 - 将是 OR。如果 Value1 被正确索引,您可能会考虑这种替代方案,至少可以测试性能差异(您需要查看计划,而不仅仅是测量时间,而您只有三行):

SELECT <cols>
  FROM dbo.Table1 
  WHERE Value1 = 'something'
UNION ALL
SELECT <cols>
  FROM dbo.Table1
  WHERE Value1 <> 'something'
  AND EXISTS (SELECT 1 FROM dbo.Table2 WHERE Value2 = Table1.Value2);

对于 NOT IN 查询,这将更可靠且至少与您提供的两个选项一样有效:

SELECT <cols>
  FROM dbo.Table1
  WHERE Value1 = 'something' 
  AND NOT EXISTS (SELECT 1 FROM dbo.Table2 WHERE Value2 = Table1.Value2);

索引在这里将是关键,但重要的是要了解 NOT IN 和 LEFT OUTER JOIN 可能会让您陷入困境。请参阅以下文章:

http://www.sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join

于 2013-01-15T19:07:19.030 回答
1
  • 这 2 个查询不等效:当使用 IN(或 NOT IN)时,对于 Table1 中的每一行,您将获得 0 或 1 个结果行。使用 join 时,每一行可能出现 0 次、1 次或多次。所以,“两个 SQL 查询返回相同的结果”——只是因为特定的数据。或 Table2 在 Value2 上具有唯一索引/PK

  • 使用 UNION 作为

SELECT ... WHERE Table1.Value1 = 'something'
UNION (ALL)
SELECT ... WHERE Table1.Value2 = Table2.Value2

也可能会给出不同的结果,因为 UNION 将删除重复项(这可能很有价值),如果 UNION ALL 与两个条件都匹配,它们可能会加倍一些结果行

  • 如果您将在第一个查询中使用 EXISTS() 而不是 IN() ......很可能您将获得相同的执行计划,因为 sql 优化器将识别这些操作是相等的并且将选择相同的最佳方式。

  • 即使您可以在语句中使用子查询,sql 优化器也可能会以不使用子查询的方式重建计划。换句话说,两个相同的查询,以不同的方式编写,很可能会针对相同的计划进行优化。

  • 对于非常复杂的查询可能无法正常工作,因为 sql 可能没有足够的时间来完整地完成优化,并在它停止的地方停止。在这种情况下,这种不同但相似的查询可能会产生不同的结果。你需要尝试和测试。

计划和性能将取决于数据、参数类型(常量、变量、计算值)、统计数据、索引……对于这些标准的某些组合,Query-1 将比 Query-2 更优化,反之亦然其他。

要获得正确答案,您需要分析和比较执行计划

于 2013-01-15T20:43:48.453 回答