代码之家  ›  专栏  ›  技术社区  ›  David

在SQL Server中,什么性能更好:其中ProcessedDate为null或其中Processed=0

  •  3
  • David  · 技术社区  · 16 年前

    我正在尝试决定在我正在设计的数据库中采用哪种方法。 我将添加一个 ProcessedDate datetime null 表中的列。当记录尚未处理时,它将为空。 Processed bit not null default 0

    通过以下查询:

    select * from tablename where ProcessedDate is null
    

    和

    select * from tablename where Processed = 0
    

    *:对每个版本的表应用适当的索引。我不是在寻找关于创建什么索引的建议。我只需要有关应用于单行的筛选器性能的信息。如果表中的所有行都需要扫描,或者查找已完成,则与手头的问题无关。

    4 回复  |  直到 16 年前
        1
  •  1
  •   erikkallen    16 年前

    一个优点是 ProcessedDate is null 谓词是指您不会冒被参数化(显式或隐式)咬到的风险。

    如果你用where Processed = 0 ,SQL server可能会在内部将此参数化为 Processed = @p ,并基于@p=0的假设生成查询计划 where Processed = 1 ,您可能会得到一个@p=1的计划,并且由于数据很可能是倾斜的,所以计划很可能是不同的。

        2
  •  3
  •   Andrew Bullock    16 年前

    就我所知,它们是相同的,数据集是相等的。您可以运行下面的示例并查看要检查的执行计划。您将看到它测试谓词的过滤器元素在每个元素中占用相同比例的时间。即使添加了索引,也不会使一个索引比另一个索引更有效,因为它们基本上是在做相同的事情。


    WITH Test (MyInt, MyNull)
    AS
    (
    SELECT 1 AS MyInt, Null AS MyNull
    
    UNION ALL
    
    SELECT 
        MyInt + 1,
        CASE
            WHEN MyInt % 2 = 0 THEN Null
            ELSE MyInt
        END
    FROM Test
    WHERE MyInt < 10000
    )
    
    SELECT * FROM Test
    WHERE MyNull IS NULL
    OPTION (MAXRECURSION 32767);
    
    WITH Test (MyInt, MyBit)
    AS
    (
    SELECT 1 AS MyInt, 0 AS MyBit
    
    UNION ALL
    
    SELECT 
        MyInt + 1,
        CASE
            WHEN MyInt % 2 = 0 THEN 0
            ELSE 1
        END
    FROM Test
    WHERE MyInt < 10000
    )
    
    SELECT * FROM Test
    WHERE MyBit = 0
    OPTION (MAXRECURSION 32767);
    

    我知道我的例子是人为的,但它使用了相等数量的空值和0。即使您将每个示例的CTE重新写入表变量,您也应该看到相同的性能。

        3
  •  2
  •   Remus Rusanu    16 年前

    与大多数SQL性能问题一样,答案将由表模式决定,而不是由SQL文本决定。就像现在一样,这两个版本都需要一个完整的表扫描,所以它们同样糟糕。

    ProcessedDate上的非聚集索引可能对第一个版本有所帮助,但由于您要求 *

    另一方面,处理了最左边键的聚集索引将始终起作用,并且这种聚集索引结构在队列处理中很常见(并且有一个'ProcessedDate'列显然表明您的表被用作队列)。

    但是聚集索引的ProcessedDate上最左边的一列也会像处理过的位一样工作。

    要带回家的教训是:不是查询,是模式。总是。

        4
  •  2
  •   Mitch Wheat    16 年前

    选择与您的域模型最匹配的一个。