2

イベントテーブルには約10万行あります。「イベント」テーブルに対する次の複雑なクエリです。このクエリを最適化する方法についてご意見をお聞かせください...

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
4

1 に答える 1

1

を削除することで、2番目のクエリを最適化できます。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//ルックアップにすでに最適です。ただし、列を追加すると、SQLiteはそれをカバーインデックスとして使用できるため、テーブル自体のレコードを検索する必要がなくなり、実際にはパフォーマンスが2倍になる可能性があります。timestampsubj_interpretationidevents

0 0 0 SCAN TABLE event USING COVERING INDEX event_subj_id_plus_id
0 0 0 USE TEMP B-TREE FOR ORDER BY
于 2013-01-04T13:22:05.010 に答える