如何以更好的方式编写查询以在两个日期之间进行检索?

moh*_*sal 0 sql sql-server query-optimization

这是我尝试的SQL查询

SELECT 
    TransactionNumber,Time
FROM 
    [HQMatajer].[dbo].[Transaction]
WHERE 
    Time>='2015-01-01' and Time<='2015-12-31'
Run Code Online (Sandbox Code Playgroud)

总记录返回280万.这需要10秒钟.

我创建了一个索引Time,并TransactionNumber为好.

还有什么我需要做的比这更快的行?

谢谢

Dis*_*ned 5

280万行是很多数据!无论怎样,它都需要一个"长"(长期相对 - 对于280万行来说是10秒是合理的).如果要改进它,请返回较少的数据.

有两种选择可能会带来边际改善:

  • CLUSTEREDTime列上创建一个.注意一个表只允许1个聚簇索引.因此,当考虑其他因素时,这可能不是一件好事.
  • 创建索引上TimeINCLUDES ^TransactionNumer

但无论哪种方式,您的问题不是查询/索引,而是数据量.


附加信息

  • 使用2个单独的索引不会有任何帮助.您的查询只能使用1个索引(无论哪个最好).
  • 我假设你TransactionNumber真的是一个数字数据类型,而不是我经常看到的可怕的"字符串数字"之一.如果您使用某种形式varchar来存储您,TransactionNumber那么最好将其更改为intbigint.这些类型需要较少的字节来存储==>意味着较少的数据==>意味着更好的性能.
  • 除非您截断Time列的时间部分,否则您的查询当前存在错误.显然,您打算返回当年的所有交易.但目前您将错过12月31日未发生的所有交易00:00.要修复此时间范围,应按如下方式过滤查询:
    • Time >= StartOfRange and Time < StartOfNextRange
    • 例如 Time >= '2015-01-01' and Time < '2016-01-01'
    • 注意:请严格注意<第二种情况.这包括明年年初之前的所有交易.

数学

我为什么说280万行的一些计算是"要返回的大量数据".

  • 您返回TransactionNumberTime.我将分别假设每行4和8个字节.(可能会更多,但这是一个非常保守的估计.)
  • 那是12 bytes * 2,800,000 = 33,600,000 bytes(大约32 MB).
  • 这只是返回的最小数据.请记住,处理的数据要多得多.包括表的其他列和索引树.
  • 要在服务器和客户端之间在10秒内传输33.6 MB的数据,需要:32 MB * 8 / 10 = 25.6即平均传输速率远远超过每秒25兆位.

结论

无论你想要做什么,都需要280万行,可能需要重新思考你的方法.但是,如果你在谈论一年一次的工作 - 那么10秒真的值得担心吗?