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

发布于 2024-09-25 16:45:44 字数 302 浏览 1 评论 0原文

我有一个与其他任何表都不相关的简单表。它有一个非 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤慢歌 2024-10-02 16:45:44

这是正常的。除非谓词的选择性足以保证它,否则它不会使用索引。

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

您可以使用 FORCESEEK 来强制您所说的行为。您可能会发现与聚集索引扫描相比,所花费的时间和 I/O 统计数据飞速增长。

SET STATISTICS IO ON

SELECT * FROM 
YourTable WITH (FORCESEEK) 
WHERE YourCol IS NOT NULL

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.

SET STATISTICS IO ON

SELECT * FROM 
YourTable WITH (FORCESEEK) 
WHERE YourCol IS NOT NULL
心的位置 2024-10-02 16:45:44

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

SQLServer(以及与此相关的任何其他关系数据库)使用统计信息来确定它将使用的查询计划。统计数据可能告诉数据库有很多行具有非空日期。因此,SQLServer 可能认为使用索引是不值得的,而 全表扫描 对于具有 NOT NULL 的特定查询来说是更好的计划> 条件。

我想提两件事:

  1. 使用查询并不总是比不使用查询更快。
  2. 您可以在查询中放置索引提示,但我通常会发现做这种优化是搬起石头砸自己的脚。

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:

  1. A query using is not always faster than a query not using one.
  2. You can place an INDEX HINT on your query but I usually find shooting myself in the foot doing that kind of optimization.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文