SQL查询的时间太慢了

时间:2013-07-11 20:10:15

标签: c# sql database sqlite optimization

我有一个包含快速文本搜索表的700,000个条目的数据库。每行都有一个与之关联的时间。我需要一次有效地分页记录100行。我是通过跟踪一天的结束来做到这一点的。

执行时间太长(15秒)

以下是一个示例查询:

SELECT * 
FROM Objects o, FTSObjects f
WHERE f.rowid = o.AutoIncID AND 
  o.TimeStamp > '2012-07-11 14:24:16.582' AND 
  o.TimeStamp <= '2012-07-12 04:00:00.000' AND 
  o.Name='GPSHistory' 
ORDER BY o.TimeStamp 
LIMIT 100

时间戳字段已编入索引。

我认为这是因为Order By语句正在对返回的所有记录进行排序,然后进行限制,但我不确定。

建议?

2 个答案:

答案 0 :(得分:2)

是的,ORDER BYLIMIT之前处理,但这是正确的功能。实际上,分页实际上不起作用。但有一些优化的想法。

  1. 如果不是绝对必要,请不要SELECT *。我感觉喜欢它可能不是因为如果您正在分页结果,几乎可以肯定不是用户正在查看的两个表格中的每个字段。
  2. AutoIncID, TimeStamp上创建一个涵盖的索引,以防止它读取数据页面。如果来自Name
  3. ,请将Objects添加到该索引
  4. rowid, Name上创建一个涵盖的索引,如果Name来自FTSObjects ,则
  5. 如果可以限制返回的字段,请考虑将这些字段添加到覆盖索引(如果只有几个字段)。您不希望索引变得太大,因为它会影响写入时间。

答案 1 :(得分:2)

最好的方法是让一个好的DBA查看生成的计划,并确保它是最优的计划(例如,确保计划中没有表扫描,如果优化器使用错误的统计信息)

这里有一些可能会有所帮助的事情:

  • Objects.Name上添加索引 - 甚至可能是NameTimeStamp上的复合索引。
  • rowidFTSObjects添加一个索引,它已经不存在
  • 定期在UPDATE STATISTICS索引上
  • Timestamp(理想情况下,在大量更新后或每天如果更新是连续的)
  • 重建您的聚集索引(如果有的话)。如果您的聚簇索引位于无法获得顺序插入的字段上(例如,插入位于随机位置的字段),这将有所帮助。
  • 不要select *如果您不需要 - 这会增加I / O时间

可能也尝试将字符串强制转换为DATETIME,尽管我认为SQL隐式执行此操作而不是将数据转换为字符串(在日期时间不使用索引)

SELECT * 
FROM Objects o, FTSObjects f
WHERE f.rowid = o.AutoIncID AND 
  o.TimeStamp > CONVERT(DATETIME,'2012-07-11 14:24:16.582') AND 
  o.TimeStamp <= CONVERT(DATETIME,'2012-07-12 04:00:00.000') AND 
  o.Name='GPSHistory' 
ORDER BY o.TimeStamp 
LIMIT 100