【问题标题】:SQL Server 2008: Ordering by datetime is too slowSQL Server 2008:按日期时间排序太慢
【发布时间】:2010-12-15 13:34:38
【问题描述】:

我的表 (SQL Server 2008) 有超过 100 万条记录,当我尝试按日期时间排序记录时,需要 1 秒,但当我按 ID (int) 排序时,只需要大约 0.1 秒。

有什么办法可以提高效率吗? (我已经在索引中添加了日期时间列)

【问题讨论】:

  • 该日期时间列是否在其自己的单独索引中?你说“添加..到索引”....如果日期时间列是例如列号3 在复合索引中,这在尝试单独按该日期时间列排序时根本无济于事............
  • 我已将它添加到现有索引中,我只是尝试创建一个新索引,它变得相对更快(0.5 秒),但仍然比 int 列慢。
  • 能否请您发布您的查询和表定义?
  • @silent:一个 DATETIME 列是 8 个字节 - 一个 INT 是 4 个字节。这意味着在您的索引页面上,INT 索引在 8K 页面上的条目数是 DATETIME 的两倍 - 无法更改。因此,INT 索引会更快,因为它会产生更少的 I/O,这是昂贵的部分。
  • @marc_s: ID 要么是集群的PRIMARY KEY,要么不是。在第一种情况下,ID 上的索引包含整个表,这比每条记录的 4 字节多得多。在第二种情况下,iddatetime 上的索引都将包含一个行指针。在这两种情况下,索引大小的差异都将小于两倍。这里重要的是Key Lookup / RID Lookup,而不是索引大小。

标签: sql sql-server sql-server-2008 sql-order-by


【解决方案1】:

在某些情况下可以将datetime设置为cluster index,如果你的表的主键不重要,例如user logs表,可以设置primary key not cluster,然后将times和user id设置为combin index并设置集群为真。

【讨论】:

    【解决方案2】:

    id 排序可能使用聚集索引扫描,而datetime 排序使用排序或索引查找。

    这两种方法都比聚集索引扫描慢。

    如果你的表是由id 聚集的,基本上就意味着它已经排序了。记录包含在B+Tree 中,其中有一个链接列表以id 顺序链接页面。引擎应该只遍历链表以获取按id 排序的记录。

    如果ids 是按顺序插入的,这意味着行的物理顺序将与逻辑顺序匹配,聚集索引扫描会更快。

    如果您希望您的记录按datetime 排序,有两种选择:

    • 从表中取出所有记录并对其进行排序。缓慢是显而易见的。
    • 使用datetime 上的索引。索引存储在磁盘的单独空间中,这意味着引擎需要在嵌套循环中在索引页和表页之间穿梭。它也更慢。

    为了提高排序,您可以在datetime上创建一个单独的覆盖索引:

    CREATE INDEX ix_mytable_datetime ON mytable (datetime) INCLUDE (field1, field2, …)
    

    ,并将您在查询中使用的所有列包含到该索引中。

    此索引类似于您的表的影子副本,但数据以不同的顺序排序。

    这将允许摆脱键查找(因为索引包含所有数据),这将使datetime 的排序与id 上的排序一样快。

    更新:

    关于这个问题的新博文:

    【讨论】:

    • 有什么有效的方法吗?
    • 我相信数据库无论如何都会以这种格式存储它(并且likey也会以这种方式比较它)。虽然一开始我也想过同样的事情,但我不认为它应该是答案。
    • +1 要优化日期时间排序,请将日期时间设为聚集索引,将 id 索引设为非聚集主键。
    【解决方案3】:

    为了遵守 ORDER BY,引擎有两种选择:

    • 使用提供请求顺序的索引扫描行
    • 对行进行排序

    第一个选项快,第二个选项慢。问题是为了使用,索引必须是一个覆盖索引。这意味着它包含 SELECT 投影列表中的所有列以及 WHERE 子句中使用的所有列(至少)。如果索引没有覆盖,那么引擎将不得不为每一行查找聚集索引(即“表”),以便检索所需列的值。这种不断查找值的成本很高,并且当引擎将(正确地)决定只扫描聚集索引并对结果进行排序时,会出现一个临界点,实际上忽略了您的非聚集索引。详情请见The Tipping Point Query Answers

    考虑以下三个查询:

    SELECT dateColumn FROM table ORDER BY dateColumn
    SELECT * FROM table ORDER BY dateColumn
    SELECT someColumn FROM table ORDER BY dateColumn
    

    第一个将在 dateColumn 上使用非聚集索引。但是第二个不会在 dateColumn 上使用索引,可能会选择扫描和排序来代替 1M 行。另一方面,第三个查询可以从Table(dateColumn) INCLUDE (someColumn) 上的索引中受益。

    这个话题在 MSDN 上有详细的介绍,请参阅 Index Design BasicsGeneral Index Design GuidelinesNonclustered Index Design GuidelinesHow To: Optimize SQL Indexes

    最终,表设计中最重要的选择是您使用的聚集索引。几乎总是将主键(通常是自动递增的 ID)保留为聚集索引,这一决定仅对某些 OLTP 负载有利。

    最后,一个相当明显的问题:你到底为什么要订购 100 万行?你不可能展示它们,对吗?稍微解释一下您的用例可能会帮助我们为您找到更好的答案。

    【讨论】:

    • 谢谢 Remus,我不想一次显示 100 万+条记录,我正在使用 row_number() 方法进行分页,但是当我尝试浏览一个大数字时发现,比如page 50000(20 rec/page),查询变得很慢,但是如果我将排序方法更改为 ID,它会快近 10 倍。
    • 我认为这一定是 row_number 分页。是LINQ吗?最好的办法是将查询表述如下:选择您感兴趣的页面的 ID(编辑第 17 页的 20 个 ID),然后检索这 20 条记录的详细信息。这可以用 T-SQL 和 LINQ 表示,而且速度足够快。您最好发布所涉及的架构和查询。
    【解决方案4】:

    您是否已将 DateTime 字段添加到“the”索引或独占索引?您是按另一个字段和 DateTime 过滤您的选择还是只过滤这个?

    您必须有一个包含您要过滤的所有字段的索引,并且最好以相同的顺序排列以优化性能。

    【讨论】:

    • 我已将它添加到现有索引中,我只是尝试创建一个新索引,它变得相对更快(0.5 秒),但仍然比 int 列慢。
    • 重要的是要对“WHERE”和“ORDER BY”语句(以及“GROUP BY”,如果有的话)中的字段进行良好的索引。它应该是相同的字段并以相同的顺序。如果您不需要表中的每一列,请仅使用所需的字段进行 SELECT。然后清除缓存和统计并尝试结果。还认为很难在具有大量数据的表中以与聚集索引相同的速度进行选择。这就是仔细选择应该是集群的原因。
    【解决方案5】:

    可能是您的 int 列有索引,但您的 datetime 列没有索引吗? 看执行计划。

    【讨论】:

    • +1 好点 - 检查执行计划!是否正在使用索引??
    【解决方案6】:

    如果您的日期时间字段包含许多不同的值并且这些值很少更改,请在日期时间字段上定义聚集索引,这将按日期时间值对实际数据进行排序。请参阅 http://msdn.microsoft.com/en-us/library/aa933131(SQL.80).aspx 了解如何使用聚簇索引。

    这将使您的 int 搜索变慢,因为它们将被降级为使用非聚集索引。

    【讨论】:

      【解决方案7】:

      将日期时间添加到新索引,将其添加到 id 索引仍然没有多大帮助。

      【讨论】:

        【解决方案8】:

        也许如果您将 datatime 存储为 int,但每次存储或获取数据时都需要时间转换。 (用于存储人员的常用技术,如 ip 地址并具有更快的查找时间)

        你应该检查你的服务器它是如何存储日期时间的,b/c 你的服务器已经将它存储为 int 或 bigint.. 它不会改变任何东西......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多