【问题标题】:Moving IF EXISTS to the WHERE clause将 IF EXISTS 移至 WHERE 子句
【发布时间】:2014-12-19 20:54:31
【问题描述】:

在此示例查询中(针对设计不佳的供应商数据库):

DECLARE @OrderNo AS CHAR(8) = LEFT(@FullOrderNo,8)

IF EXISTS (SELECT 1 FROM Foo WHERE FullOrderNumber = @FullOrderNo)

    SELECT  Stuff
    FROM    Foo
    WHERE   X = 'Y'
            AND FullOrderNumber = @FullOrderNo

  ELSE

    SELECT  Stuff
    FROM    Foo
    WHERE   X = 'Y'
            AND OrderNumber = @OrderNo

由于 SELECT 和 WHERE 子句的第一部分是相同的,有没有办法安全地组合查询同时确保首先检查 FullOrderNumber 匹配项?我看到有no guarantees for WHERE clause evaluation order

【问题讨论】:

  • WHERE FullOrderNumber = @FullOrderNo OR OrderNumber = @OrderNo
  • @M.Ali:当有FullOrderNumber = @FullOrderNo的记录时,这将返回OrderNumber = @OrderNo不需要的记录
  • @M.Ali 如果在表中的任何地方都没有 FullOrderNumber 匹配项,我只想匹配 OrderNumber。

标签: sql sql-server performance query-optimization


【解决方案1】:

你可以这样写:

SELECT  Stuff
FROM    Foo
WHERE   X = 'Y' AND
        (FullOrderNumber = @FullOrderNo OR
         (NOT EXISTS (SELECT 1 FROM Foo WHERE FullOrderNumber = @FullOrderNo) and OrderNumber = @OrderNo) )

如果您只寻找一行,您可以使用order by 进行优先排序:

SELECT  TOP (1) Stuff
FROM    Foo
WHERE   X = 'Y' AND
        (FullOrderNumber = @FullOrderNo OR OrderNumber = @OrderNo)
ORDER BY (CASE WHEN FullOrderNumber = @FullOrderNo THEN 1 ELSE 2 END)

其实就算有重复,你也可以这样使用with ties

SELECT  TOP (1) WITH TIES Stuff
FROM    Foo
WHERE   X = 'Y' AND
        (FullOrderNumber = @FullOrderNo OR OrderNumber = @OrderNo)
ORDER BY (CASE WHEN FullOrderNumber = @FullOrderNo THEN 1 ELSE 2 END)

【讨论】:

  • 这些例子可能会将两个语句重写为一个;但他们不保证:that FullOrderNumber matches are checked first。如果 FullOrderNumber 上有索引,但 OrderNumber 上没有索引,则它可能会执行全表扫描(据推测 OP 试图通过此要求避免)。
  • @Gerrat 。 . .我将其解释为“首先返回完整的订单号”。但是,我不太确定 OP 是什么意思。
  • @GordonLinoff - 谢谢;澄清一下,我宁愿避免表扫描。如果原版表现更好,我会坚持下去。
  • @TrueWill 。 . . or 通常会导致表扫描。但是,数据的大小和第一个过滤器的选择性对性能有很大影响。
  • 在答案中的第一个 SELECT 中,我认为您需要在表达式的 OR 部分周围加上括号。否则,它可以返回匹配 X <> 'Y'.
猜你喜欢
  • 1970-01-01
  • 2013-04-17
  • 2015-09-25
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
相关资源
最近更新 更多