【发布时间】:2020-12-31 11:04:02
【问题描述】:
我有一个有两个日期时间列的大表。
[Timestamp] 和 [TimestampRounded]
[Timestamp] 列具有完整的时间戳(包括毫秒),并且该表没有该列的索引。
[TimestampRounded] 列具有时间戳,但毫秒、秒和分钟被截断(设置为 0)。该表具有该列的聚集索引。即,表格有效地按此列的顺序存储。通常,最新的行位于表格的顶部。索引是这样创建的:
CREATE CLUSTERED INDEX cidx_time ON [dbo].[MyTable] ([TimestampRounded] DESC)
现在,我想利用我的聚集索引检索一些数据,所以我执行以下选择,我的表有大约 500 万行。
查询 1:
SELECT TOP(100) * FROM [dbo].[MyTable] ORDER BY [TimestampRounded] DESC
此查询立即返回(不到 1 秒)。但是返回的 100 行没有按毫秒排序,只是按小时排序。
然后我知道我是否也想按第二列排序:
查询 2:
SELECT TOP(100) * FROM [dbo].[MyTable] ORDER BY [TimestampRounded] DESC, [Timestamp] DESC
这个查询非常慢,大约需要 23 秒才能返回 100 行。
我的直接解决方案是使用第一个查询,然后在我的客户端前端代码中对返回的 100 行进行排序。但是我遇到了一些问题,我错过了应该返回的行,所以我想了解如何修复/重写查询 2 以按预期返回这 100 个排序的行,并且通过合理的逻辑也应该花费不到 1 秒。由于该表已经按小时存储(聚集索引),我不明白为什么需要更长的时间。
【问题讨论】:
-
TimestampRounded有多少行在相同的最高值上? -
可以将数千行绑定到 TimestampRounded 值。那就是在那一小时内发生的每一行
-
完全正确 - 所以您的第一个查询是“给我 any 100 行共享相同小时值的行” - 而您的第二个查询是“给我准确的 100 行最新的” - 第二个需要更多时间。
-
那么获得正确数据的合理性是什么?对聚集索引使用 [Timestamp]?据我所知,这不是最优的,因为索引将是不合理的,特别是由于时间戳中的毫秒和秒
-
我用这个问题的答案作为参考:stackoverflow.com/questions/17381875/…
标签: sql sql-server performance sql-order-by query-optimization