代码之家  ›  专栏  ›  技术社区  ›  Pablo Castilla

SQL Server不使用将日期时间与非空值进行比较的索引

  •  5
  • Pablo Castilla  · 技术社区  · 14 年前

    我有一张简单的桌子,与其他桌子没有任何关系。它有一个非pk列,表示它是日期。我已经为该列创建了一个非聚集索引。如果我提出这个问题:

    从dateColumn不为空的表中选择“*”<--不使用索引,速度非常慢。

    但是如果我去掉了not,这样: 从datecolum为空的表中选择“*”<--使用索引,速度非常快。

    没有空值比空值多得多。

    我忘了什么吗?我可以在这里使用筛选索引吗?

    事先谢谢。

    2 回复  |  直到 14 年前
        1
  •  4
  •   Martin Smith    14 年前

    这是正常现象。它不会使用索引,除非谓词有足够的选择性来保证它。

    听起来绝大多数记录都不是空的,因此不必通过非聚集索引来查找这些记录,而是必须执行大量的书签查找和随机I/O来检索其余的列以返回,只需扫描整个聚集索引就可以更快、更高效。

    你可以用 FORCESEEK 强迫你所说的你想要的行为。与聚集索引扫描相比,您很可能会发现所用的时间和I/O统计信息会经过顶部。

    SET STATISTICS IO ON
    
    SELECT * FROM 
    YourTable WITH (FORCESEEK) 
    WHERE YourCol IS NOT NULL
    
        2
  •  1
  •   Pablo Santa Cruz    14 年前

    理解你的问题的关键可能在这句话中: 没有空值比空值多得多 .

    SQL服务器 (以及其他关系数据库)使用统计信息来确定它将使用什么查询计划。统计信息可能告诉数据库有很多日期为非空的行。所以也许 SQL服务器 认为使用一个索引是不值得的, 全表扫描 对于这个特定的查询,更好的计划是 不为空 条件。

    我想提两件事:

    1. 一个查询 使用 并不总是比查询更快 不使用 一。
    2. 你可以放一个 索引提示 你问我的问题,但我通常会发现我是在做那种事 优化