(以下の更新を参照)
C#.Net アプリケーション内から約 500,000 行の非常に単純な Sqlite データテーブルをクエリすると、クエリのパフォーマンスが低下するという問題があります (約 5 秒)。
LinqPad と 2 つのデータベース ブラウザー (どちらも QtSql ベース) を使用して、まったく同じデータベースでまったく同じクエリを試しましたが、10 倍高速 (~0.5 秒) で実行されます。同じクエリ、同じデータベース、異なるアプリ、私のものだけが高速に動作しません。
値を返すか、単に Count(*) を返すかに関係なく、ほとんど違いはありません。
私はもう試した:
- .Net 3.5/4/4.5のそれぞれのビルド
- AnyCPU/x86/x64のそれぞれのビルド
- System.Data.Sqlite、sqlite-net のそれぞれを使用し、COM 経由で sqlite3 dll に直接アクセスする
- WPF/WinFormごとにビルド
- クエリのさまざまなバリエーション
これらのどれも、クエリ時間に顕著な違いをもたらしません。
JOIN を使用してクエリを書き直すと役立つことはわかっていますが、LinqPad/Sql ブラウザーでは同じクエリが正常に機能するのに、作成しようとしているアプリでは機能しない理由がわかりません。かなり基本的な何かが欠けているに違いありません。
例の表:
"CREATE TABLE items(id INTEGER PRIMARY KEY, id1 INTEGER, id2 INTEGER, value INTEGER)"
クエリ文字列の例 (基本的に、サブクエリを使用するクエリはすべて時間がかかります):
SELECT count(*)
FROM items WHERE
id2 IN
(
SELECT DISTINCT id2 FROM items WHERE id1 IN
(
SELECT DISTINCT id1 FROM items WHERE id2 = 100000 AND value = 10
)
AND value = 10
)
AND value = 10
GROUP BY id2
これはおそらく JOINS とインデックス作成を使用して書き直して高速化できることはわかっていますが、このクエリは他のアプリよりもはるかに高速に動作するという事実は変わりません。何を試しても同じクエリの実行が非常に遅くなる理由について、ここで何が欠けていますか?
更新: sqlite のバージョンが問題に関係しているようです。従来の System.Data.Sqlite v1.0.66.0 を使用すると、クエリは他のアプリと同じように実行されますが、より新しいバージョンを使用すると遅くなります。これがどのバージョンで正確に何を変更したかは特定していませんが、具体的には System.Data.Sqlite ではなく、基礎となる sqlite3 バージョンに関係していると確信しています。この状況でサブクエリが非常に遅くなる原因となる変更を誰かが知っている場合、または sqlite の新しいバージョンでサブクエリをより速く実行できる設定または何かがある場合は、私に知らせてください!
繰り返しますが、クエリは例であり、理想的ではなく、部分的に冗長です...問題は、なぜ一方では機能し、他方では機能しないのかについてです。
追加のご意見をお寄せいただきありがとうございます。
更新:解決済み
以下の私の答えを見てください。