SQL Server 不使用索引将日期时间与非空进行比较
我有一个与其他任何表都不相关的简单表。它有一个非 PK 列,它是一个日期。我已经为该列创建了一个非聚集索引。如果我进行此查询:
select * from table where datecolumn is not null <-- 不使用索引并且速度非常慢。
但如果我删除 not,这样: select * from table where datecolum is null <-- 使用索引并且速度非常快。
非空值比空值多得多。
我是不是忘记了什么?我可以在这里使用过滤索引吗?
提前致谢。
I have a simple table not related to any other. It has a not PK column that it is a date. I have created a non-clustered index to that column. If I make this query:
select * from table where datecolumn is not null <-- does not use the index and goes really slow.
But if I remove the not, this way:
select * from table where datecolum is null <-- uses the index and goes really fast.
There are much more not nulls than nulls.
Am I forgetting something? Could I use filtered index here?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是正常的。除非谓词的选择性足以保证它,否则它不会使用索引。
听起来绝大多数记录都不为 NULL,因此不必通过非聚集索引查找这些记录,而是必须进行大量书签查找和随机 I/O 来检索其余列以返回,这样更快、更高效只需扫描整个聚集索引。
您可以使用
FORCESEEK
来强制您所说的行为。您可能会发现与聚集索引扫描相比,所花费的时间和 I/O 统计数据飞速增长。This is normal. It won't use the index unless the predicate is selective enough to warrant it.
It sounds like the vast majority of records are not NULL so instead of finding these via the non clustered index then having to do loads of bookmark lookups and random I/O to retrieve the rest of the columns to return it is quicker and more efficient to just scan the whole clustered index.
You can use
FORCESEEK
to force the behaviour that you say you want. You will likely find that the time taken and I/O stats go through the roof compared to the clustered index scan.理解你的问题的关键可能就在这句话中:非空值比空值多得多。
SQLServer(以及与此相关的任何其他关系数据库)使用统计信息来确定它将使用的查询计划。统计数据可能告诉数据库有很多行具有非空日期。因此,SQLServer 可能认为使用索引是不值得的,而 全表扫描 对于具有 NOT NULL 的特定查询来说是更好的计划> 条件。
我想提两件事:
The key to understand your issue is probably in this sentence: there are much more not nulls than nulls.
SQLServer (and any other relational db for that matter) uses statistics to determine what's the query plan it is going to use. Statistic are probably telling the database that there are a lot of rows with non null dates. So maybe SQLServer is thinking that using an index it's not worth it and a FULL TABLE SCAN is a better plan for that specific query with that NOT NULL condition.
Two things I want to mention: