1

メモリ マップド パーティションにある sqlite3 db にテーブルがあります。このクエリ プランでは、次のような select ステートメントがあります。

sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, 
sst.rate_n, sst.interval_1, sst.interval_n
FROM sch AS sst
WHERE
sst.i_workbook_id = 989 AND 
sst.prefix IN ('', '1', '19', '191', '1919', '19198') AND 
sst.activation_date <= DATETIME('now') AND 
(sst.expiration_date > DATETIME('now') OR sst.expiration_date IS NULL) AND
sst.start_time <= TIME('now') AND 
sst.end_time >= TIME('now');


0|0|0|SCAN TABLE sch AS sst (~185 rows)
0|0|0|EXECUTE LIST SUBQUERY 1

ここで注文を追加すると、彼のクエリ プランはメイン テーブルに 2 回ヒットし、以前よりも 4 倍長くかかります。テーブルには 130 万行ありますが、フィルター処理された行は 2 つだけです。

新しいクエリ プランは次のとおりです。

sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, 
sst.rate_n, sst.interval_1, sst.interval_n
FROM sch AS sst
WHERE
sst.i_workbook_id = 989 AND 
sst.prefix IN ('', '1', '19', '191', '1919', '19198') AND 
sst.activation_date <= DATETIME('now') AND 
(sst.expiration_date > DATETIME('now') OR sst.expiration_date IS NULL) AND
sst.start_time <= TIME('now') AND 
sst.end_time >= TIME('now') order by sst.prefix;     

0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|SEARCH TABLE sch AS sst USING AUTOMATIC COVERING INDEX (i_workbook_id=?) (~7 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|SEARCH TABLE sch AS sst USING AUTOMATIC COVERING INDEX (i_workbook_id=?) (~7 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR ORDER BY

何か案は?私は何を間違っていますか?

4

1 に答える 1

2

SQLite は、i_workbook_id列に一時インデックスを作成して、2 番目のクエリを最適化しようとします。OR式をより適切な方法で最適化できないため、そのルックアップは複数回行われます。(クエリ オプティマイザークエリ プランナーのドキュメントを参照してください。)

あなたがしようとすることができることは

  • i_workbook_id列にインデックスを作成します。または
  • i_workbook_idprefix列の両方にインデックスを作成します。または
  • 最初にこれら 2 つの列にカバリングインデックスを作成し、次にSELECTandWHERE節で言及されている他のすべての列に作成します。
于 2013-01-05T10:20:39.247 に答える