2012-07-10 18 views
8

キーワードに基づいてデータを取得する必要がありますが、クエリは100%正確にテストされていますが、問題はreaderの読み込みがかなり遅いことです。私はinner joinが全く含まれていないものでこのクエリを置き換えようとしましたが、ロードはかなり高速でした。結果として1つの列しか選択しないので、なぜDataTable.Load()に時間がかかるのですか? SQLiteExecuteReaderは、1つの列だけでなく結果全体をロードしますか?DataTableリーダーの読み込みが非常に遅い

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(); 
+1

あなたの質問は単純に遅いようです。あまりにも多くの結合を行う必要がないように、テーブルにアクセスする別の方法はありますか? – Tejs

+0

私はこれが痛いことを知っていた。残念ながら、フィールドの1つに基づいて2つのテーブルを接続する必要があります。これらの結合は、現在のDBスキーマを考慮すると、それらの間の唯一の接続です。 – iCantSeeSharp

+0

'_database'とは​​何ですか?なぜ、' Connect'や 'Disconnect'のようなメソッドを持っていますか?車輪を再構築しないでください。また、接続のために 'using-statement'を使用して、できるだけ早く「閉じられる」ようにする必要があります。これはASP.NETのようなマルチスレッド環境ですか? –

答えて

2

The SQLite Query Plannerは、SQLiteのクエリ最適化に関するヒントを提供します。

あなたの質問に適用される場合がありますいくつかの項目:

のSQLiteの現在の実装では、唯一使用しています:あなたは、複数の結合順序を再しようとするかもしれないのSQLiteでの実装に起因する

1)ループ結合。つまり、 には、結合はネストされたループとして実装されています。結合のネストされたループのデフォルトの順序は、FROM句の一番左の表の方が外側のループを形成する になり、内側のループを形成するために最も右側の表が作成されます。

したがって、JOINの構築方法によっては、パフォーマンスに差が生じることがあります。

SQLiteはこれを自動的に最適化しようとしますが、私の知る限りでは、ドキュメントを理解されるように(私がハイライト)成功のための保証はありません。しかし

、SQLiteは巣異なる順序でループがやってするかどうかそのため、より良い指標を選択するのに役立ちます。 [...] 結合リオーダリングは自動的に行われ、通常、プログラマは を考慮する必要はありません。特に、ANALYZEを使用して利用可能なインデックスについての の統計情報を収集している場合は特に問題ありません。 しかし時々、 プログラマーからのヒントが必要です。

2)また、INNERが内部WHERE句ので、あまりにも文書のセクションが適用される場合がありますで、パフォーマンスのヒント、のいずれかに変換され、参加することに注意してください。

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

3)あなたはそれらのすべてのインデックスがある場合は、あなたの文で複数の列を選択するために検討するかもしれない:

それはWHEREに表示されるインデックスの列ごとに必要ではありません その索引が使用されるためには、節の項が必要です。しかし、は、使用されているインデックスの列の間隙である にはなりません。

+0

すべての結合は主キーで構築されていますが、これはインデックス作成に関する問題を解決すると思いますが、1 + 2が私の場合に救命救助者になるかどうかを考えています。 – iCantSeeSharp

+0

私のSQLコマンドの前に 'ANALYZE'を使用しましたが、クエリはかなり速く実行されました。したがって、あなたがこの特定の問題の正しい方向を示したと考えると、答えが得られます。ありがとう! – iCantSeeSharp

3

私は、これはSQLiteのと合流する多数の性質により起こると思います。

データベースのスキームをリファクタリングして、データを非正規化してより高速にアクセスできるようにしてください。

+0

"nature of SQLite"は、期待される結果が現在返されている結果と異なることを意味しますか? – iCantSeeSharp

+0

@Souvlaki:SQLiteはこのような数のジョインに適したロードをサポートしていないことを意味します。また、結果として得られる耐久性を低下させる大きなファイルがあるかもしれません。 – abatishchev

+0

Navicatではクエリがかなり高速ですが? – iCantSeeSharp

関連する問題