【问题标题】:Understanding about SQL index on DateTime Column了解 DateTime 列上的 SQL 索引
【发布时间】:2021-03-10 04:27:00
【问题描述】:

我有大约 100 万条记录。在日期范围内搜索时,速度非常慢。然后我做了谷歌搜索,有人建议在“日期时间”列上做索引。我不相信,因为我一直认为索引是用于 O(1) 搜索——这意味着相等搜索;而且由于我的查询是日期范围搜索,如何才能提高性能?

但是,出于好奇,我还是尝试了,令我惊讶的是,它确实显着提高了性能。

这是我的桌子

tblOrder
--------
OrderId (Primary Key)
CurrencyId
ProductId
...
...
...
OrderDate DATETIME

我正在使用 linqtosql,代码是:

return (from rec in tblOrders.AsNoTracking()
        where (rec.CurrencyId == CurrencyId) && (rec.OrderDate >= startDate) && (rec.OrderDate < endDate)
        select rec).ToList();

我在CurrencyIdOrderDate 上都创建了SQL 索引。结果是巨大的进步。我的问题是,这怎么可能?为什么索引在范围搜索(不等于但>= 或

谢谢...

【问题讨论】:

  • “因为我一直认为索引是用于 O(1) 搜索的” 这种思路是错误的。如果我让你在电话簿中列出所有的“史密斯”,你就不会在写完之后再回到书的开头;你会去下一个而无需重新开始。 RDBMS 也不例外。
  • 另外,为了确保索引有用,您需要确保它被覆盖。如果您也在处理查询中的其他列(包括在SELECT 中),那么仅在日期时间列上添加索引可能没有帮助。
  • 索引搜索独立于数据类型。对于范围搜索,它找到从(下限)开始的第一个元素并读取所有行引用,直到上限。但不要忘记列顺序很重要:datefield, idfield 上的索引会更慢,因为 DBMS 将检查每个日期的该 ID
  • @Larnu 最好说这取决于与总行数相比将选择多少行。此示例中的单个日期和字段名称上下文应该更快
  • 如果您想询问索引是如何工作的,@Sam,您应该在 Database Administrators 上询问它们。

标签: sql sql-server linq-to-sql database-indexes


【解决方案1】:

索引本质上是索引键的有序列表,其中附加了它们引用的行的地址。您可以使用相等条件来相对快速地跳转到索引的任何点,方法是按照您正在搜索的值。一旦达到这一点,您将继续阅读有序数据,直到它不再满足您的访问搜索。对于范围谓词,这意味着跳转到范围内的最小值并开始读取,直到出现大于最大范围值的值。

【讨论】:

    【解决方案2】:

    对于这个where 子句:

        where (rec.CurrencyId == CurrencyId) && (rec.OrderDate >= startDate) && (rec.OrderDate < endDate)
    

    您想要一个前两列是(CurrencyId, OrderDate) 的复合索引。

    【讨论】:

    • 嗨,戈登,是的,我确实创建了一个复合索引。但我的问题是日期索引在范围搜索方面如何工作? (ps。我没有没有投反对票)
    猜你喜欢
    • 2016-05-09
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多