1

entry (~70k 行)、tag (~27k 行)、entry_tag (~2.5M 行)の 3 つのテーブルがある単純な SQL テーブル構造があります。entry_tag -tableには、このentry_tag ( entry_idtag_id... )のようなエントリとタグ間の関係 (nn 関係) が含まれています。

特定のタグを持つすべてのentry_idを最初に取得しようとしたとき、次のようなクエリを作成しました

SELECT entry_id FROM entry_tag et, tag t 
WHERE t.id=et.tag_id AND t.name LIKE 'Something';

明らかな理由もなく、Win7 x64 (i5-2500K、8GB RAM、7200rpm hdd) 上の Adob​​e Air アプリでクエリに 6 秒以上かかりました。これは遅すぎます (特に複雑なINTERSECTクエリの場合)。SQLite コマンド ライン ツールでは、クエリはすぐに結果を返しました。cli と Air (Air ベースの SQLite Sorcerer を使用)を比較EXPLAINし、結果は同じでした。EXPLAIN QUERY PLANどちらのクエリもインデックスを使用していました。

テーブルの順序を入れ替えてクエリを再構築した後、Air でのパフォーマンスは 250 ミリ秒に倍増しました。これは満足のいくものです。

SELECT entry_id FROM tag t, entry_tag et
WHERE et.tag_id=t.id AND t.name LIKE 'Something';

では、なぜ cli ツールが Adob​​e Air 環境よりもはるかに高速なのか疑問に思っていました。背景情報として、PHP で db ファイルを生成しました (すべての列INTEGERまたはTEXT)。

元のスロー クエリのクエリ プランは次のとおりです。

sele  order          from  deta
----  -------------  ----  ----
0     0              0     SCAN TABLE entry_tag AS et USING INDEX idx_et_eid (~1000000 rows)
0     1              1     SEARCH TABLE tag AS t USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)

(〜1000000行はとにかく悪いように見えます;)

4

0 に答える 0