【问题标题】:Improve querying table using dates使用日期改进查询表
【发布时间】:2015-08-12 13:41:24
【问题描述】:

我有一个包含大量数据的表,我想使用日期范围查询它。

这是查询

SELECT TOP (10000) 
    [PositionId] AS [PositionId], 
    [DeviceId] AS [DeviceId],     
    [Course] AS [Course], 
    [Latitude] AS [Latitude], 
    [Longitude] AS [Longitude], 
    [Speed] AS [Speed], 
    [MomentTiming] AS [MomentTiming],                             
    [Fuel] AS [Fuel], 
    [Ignition] AS [Ignition]        
 FROM
    [PositionInsights]
 WHERE
    deviceId = 352 
    AND [MomentTiming] >= '8/12/2015 7:38:00 AM' 
    AND [MomentTiming] <= '8/12/2015 3:38:00 PM'

问题是这个简单的查询花费了太多时间,大约 35 秒

【问题讨论】:

  • 表中有多少条记录?
  • 表上有哪些索引?如果deviceId 字段上没有索引,则在该字段上添加索引将提高性能。什么是聚集索引?如果这是针对该表运行的最常见(频繁)查询,我建议在列 deviceIdMomentTiming 以及任何主键列上使用一个集群索引。
  • 访问此链接可能会有所帮助,stackoverflow.com/questions/1716798/…
  • @NickBullatovci 百万记录
  • @CharlesBretana 唯一存在的索引在主键 positionId 上

标签: sql-server


【解决方案1】:

作为一般规则,您的 where 子句中的任何字段都应该被索引。如果您在表上执行大量 CRUD,您应该确保索引不会随着时间的推移而碎片化。 所以我会创建两个单独的索引,一个在 deviceid 字段上,另一个在 MomentTiming 字段上。 如果您的表有数百万或数十亿行,您可能希望在其中一个字段上设置表分区。如果 deviceid 字段是自动编号字段,那么这可能是一个足够好的范围分区值,否则在您的 MomentTiming 日期字段上进行分区。如果你分区,保持索引和我描述的一样。

更新:由于您只有数百万行,而不是数十亿行,因此只需从索引开始,看看会发生什么。但是,如果您的数据增长很快,您可能还是想看看分区。另外,如果你走分区路线,你应该尝试将不同的文件放在不同的挂载点上以获得最佳性能。

HTH

【讨论】:

  • 另一种想法是您可以将日期存储为 bigint,因为有很多观点认为基于数字的索引通常可以提供更快的查找
  • datetimes 已经是一个显示为日期时间的数值。我怀疑这是否会提高性能
猜你喜欢
  • 2018-07-29
  • 2017-01-17
  • 1970-01-01
  • 2016-03-23
  • 2011-07-01
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多