2013-07-11 45 views
1

我有70万项与快速文本搜索表的数据库。每一行都有与之关联的时间。我需要一次有效地分页记录100行。我通过追踪一天的结束来做到这一点。SQL查询太慢

它走太长时间来执行(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语句排序的所有返回的记录,然后做一个限制,但我不知道。

对此提出建议?

+0

上'Timestamp'是我的建议索引。 – Matthew

+0

时间戳索引@Matthew –

+0

一个连接语法也可能在这里帮助'JOIN FTSObjects f ON f.rowid = o.AutoIncID',但我认为优化器已经为你做了。 – Matthew

回答

2

最好的办法是得到一个好的DBA来看看所产生的计划,并确保它是最优的计划(如确保有在计划中没有表扫描,如果优化它可以发生使用不好统计)

这里有一些事情可以帮助:

  • Objects.Name添加索引 - 上NameTimeStamp甚至可能是一个复合索引。
  • rowidFTSObjects添加一个索引它尚不上Timestamp指数存在
  • UPDATE STATISTICS定期(最好经过大更新或每日更新是否连续)
  • 重建你的聚集索引(如果有的话)。如果您的聚簇索引位于不能顺序插入的字段上(如一个char场,其中嵌在随机的地方)
  • 不要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 
+0

我认为我们的SQLite实现接受DateTime参数,但只是在内部使用字符串......不确定。 你有一个DBA的建议,让我看看使用EXPLAIN QUERY PLAN命令。这让我看到一个糟糕的索引被使用。 classname列已编入索引,但只有6个唯一名称。我得到了使用Timestamp作为索引的查询,现在事情快了大约15倍。 –

2

是的,ORDER BYLIMIT之前被处理,但是这是正确的功能。否则,寻呼实际上不会起作用。但有一些想法用于优化。

  1. 如果不是绝对必要的,则不要SELECT *。我觉得它可能不是,因为如果你分页结果它几乎肯定不会在表用户正在寻找每一个领域。
  2. AutoIncID, TimeStamp创建覆盖索引,以防止它读取数据页。如果它来自Objects,请将Name添加到该索引。
  3. rowid, Name,上创建一个覆盖指数Name来自FTSObjects
  4. 如果返回的字段可以被限制,考虑增加这些领域的覆盖指标如果这只是一对夫妇领域。您不希望索引变得太大,因为那样会影响写入时间。
+1

解决方案必须使用错误的索引。该classname列只有六个唯一的名称,并被编入索引。我强制使用时间戳索引,现在页面在1秒内收集起来。我试图创建覆盖指数,但他们似乎并没有改善... –