改进SQLite查询

时间:2012-12-27 00:37:10

标签: sql sqlite

我有一个事件表,其中有大约100k行。 关于“事件”表的以下复杂查询,并希望就如何优化此查询发表意见......

SELECT id FROM event 
NATURAL JOIN (
    SELECT subj_id, max(timestamp) AS timestamp
    FROM event WHERE (
        timestamp >= 1342052128597 AND timestamp <= 9223372036854775807
        AND NOT subj_interpretation = 46))
    GROUP BY subj_id)
GROUP BY subj_id
ORDER BY  
timestamp DESC

查询在此处执行0.06-0.07秒。任何有关查询的良好指示和/或重构的想法。

目前我正在使用:

CREATE INDEX event_subj_id ON event(subj_id, timestamp, subj_interpretation)

查询计划如下:

1 0 0 SCAN TABLE event USING COVERING INDEX event_subj_id (~27777 rows)
0 0 1 SCAN SUBQUERY 1 (~100 rows)
0 1 0 SEARCH TABLE event USING INDEX event_subj_id (subj_id=? AND timestamp=?) (~9 rows)
0 0 0 USE TEMP B-TREE FOR GROUP BY
0 0 0 USE TEMP B-TREE FOR ORDER BY

1 个答案:

答案 0 :(得分:1)

您可以通过删除DISTINCT来优化第二个查询,因为GROUP BY subj_id已经确保不存在重复记录:

SELECT id,
       subj_id,
       max(timestamp) AS timestamp
FROM event
WHERE timestamp BETWEEN 1342055894621 AND 9223372036854775807
  AND subj_interpretation != 46
GROUP BY subj_id
ORDER BY timestamp

索引本身已经是GROUP BY / timestamp / subj_interpretation查找的最佳选择。 但是,如果向其添加id列,SQLite可以将其用作覆盖索引,这样就无需查找events表本身中的任何记录,这可能实际上使性能翻倍:

0 0 0 SCAN TABLE event USING COVERING INDEX event_subj_id_plus_id
0 0 0 USE TEMP B-TREE FOR ORDER BY