8

キーワードに基づいていくつかのデータをフェッチする必要があります。クエリは100%正確にテストされますが、問題はの読み込みreaderがかなり遅いことです。このクエリをsをまったく含まないクエリに置き換えてみましたがinner join、読み込みはかなり高速でした。結果として1つの列しか選択していないのに、なぜDataTable.Load()にそれほど時間がかかるのでしょうか。1つの列だけでなく、結果全体をロードするのはSQLite'sですか?ExecuteReader

DataTableを使用する前は、それぞれを実行する平均時間reader.Read()は7秒でした。

これは私のコードです:

_database.Connect();

var selectCommand = new SQLiteCommand(
@"SELECT A.ID AS MY_ID FROM MD 
INNER JOIN TMD ON MD.ID = TMD.ID_MD 
INNER JOIN TR ON TR.ID = TMD.ID_TR 
INNER JOIN P ON P.ID = TR.ID_P 
INNER JOIN DP ON DP.ID_P = P.ID 
INNER JOIN CD ON CD.ID = DP.ID_CD 
WHERE CD.DESC = @desc"
);

selectCommand.Parameters.AddWithValue("@desc", value);

using (DbDataReader reader = _database.ExecuteQuery(selectCommand))
{
    DataTable data = new DataTable("MyData");
    data.Load(reader);
}
_database.Disconnect();
4

2 に答える 2

3

これは、SQLiteの性質と多数の結合が原因で発生すると思います。

アクセスを高速化するためにデータを非正規化するなど、データベーススキームをリファクタリングしてみてください。

于 2012-07-10T13:54:35.300 に答える
2

SQLiteクエリプランナーは、SQLiteのクエリ最適化に関するヒントを提供します。

あなたの質問に当てはまるかもしれないいくつかの項目:

1.)SQLiteでの実装により、複数の結合を並べ替えようとする場合があります。

SQLiteの現在の実装では、ループ結合のみを使用しています。つまり、結合はネストされたループとして実装されます。結合内のネストされたループのデフォルトの順序は、FROM句の左端のテーブルが外側のループを形成し、右端のテーブルが内側のループを形成することです。

したがって、JOINの構築方法によっては、パフォーマンスに違いが生じる可能性があります。

SQLiteはこれを自動的に最適化しようとしますが、ドキュメントを理解している限り、成功の保証はありません(私が強調表示しています)。

ただし、SQLiteは、より適切なインデックスを選択するのに役立つ場合は、ループを異なる順序でネストします。[...]結合の並べ替えは自動的に行われ、通常は十分に機能するため、プログラマーはそれについて考える必要がありません。特に、ANALYZEを使用して、使用可能なインデックスに関する統計を収集している場合はそうです。ただし、プログラマーからのヒントが必要になる場合があります。

2.)また、INNER JOINSは内部でWHERE句に変換されるため、ドキュメントのWHEREセクションにあるパフォーマンスのヒントも適用される可能性があることに注意してください。

内部結合のON句とUSING句は、上記の段落1.0で説明したWHERE句の分析の前に、WHERE句の追加の用語に変換されます。したがって、SQLiteでは、古いSQL89コンマ結合構文よりも新しいSQL92結合構文を使用することによる計算上の利点はありません。どちらも、内部結合でまったく同じことを実行することになります。

3.)インデックスがある場合は、ステートメントでさらに列を選択することを検討してください。

インデックスを使用するために、インデックスのすべての列がWHERE句の用語に含まれている必要はありません。ただし、使用されるインデックスの列にギャップを設けることはできません。

于 2012-07-10T14:27:00.883 に答える