C#を使用して、SqlServerのテーブルからメモリの配列に文字列の1列をロードする必要があります。 SqlDataReaderを開いてループするよりも速い方法はありますか。テーブルは大きく、時間が重要です。
編集私は.dllを構築し、データベース上のいくつかの操作のためにサーバー上でそれを使用しようとしています。しかし、それは今のところ遅くすることです。これが最速の場合、データベースを再設計する必要があります。物事をスピードアップする方法がいくつかあるかもしれません。
データリーダー
SQLにアクセスする最速のアクセスについては、 SqlDataReader を使用します。
それをプロファイルする
パフォーマンスの問題がどこにあるかを実際にプロファイリングする価値があります。通常、パフォーマンスの問題があると思われる場所は、プロファイルを作成した後に完全に間違っていることが証明されています。
たとえば、次のようになります。
これらをそれぞれ個別にプロファイリングすることで、ボトルネックがどこにあるかをより正確に把握できます。コードのプロファイリングには、 Microsoftのすばらしい記事 があります
キャッシュする
パフォーマンスを改善するために見るべきことは、毎回すべてのデータをロードする必要がある場合ifを解決することです。リスト(またはその一部)をキャッシュできますか?新しい System.Runtime.Caching 名前空間を見てください。
T-SQLとして書き換える
(質問が示唆するように)純粋にデータ操作を行う場合、データを使用するコードをT-SQLに書き換えて、SQLでネイティブに実行できます。これにより、データを直接操作し、データをシフトしないため、はるかに高速になる可能性があります。
コードに必要な手続き型ロジックがたくさんある場合は、T-SQLと CLR Integration を組み合わせて使用すると、両方の利点が得られます。
これは、ロジックの複雑さ(またはより手続き的な性質)に大きく依存します。
他のすべてが失敗した場合
すべての領域が最適(またはそれに近い)であり、設計に問題がない場合。私はマイクロ最適化すらしません。ただ ハードウェアを投げる です。
どのハードウェアですか? 信頼性とパフォーマンスモニター を試して、ボトルネックがどこにあるかを調べます。 HDDまたはRAMについて説明する問題の最も可能性の高い場所。
SqlDataReader
の速度が十分でない場合は、(メモリ内)キャッシュなど、他の場所に何かを保存する必要があります。
いいえ。実際には最速の方法であるだけでなく、唯一の(!)方法です。とにかく、他のすべてのメカニズムは内部的にDataReaderを使用します。
SqlDataReader
は、あなたが手に入れようとしているものとほぼ同じだと思います。
SqlDataReaderは最速の方法です。列名で取得するのではなく、順序による取得メソッドを使用してください。例えばGetString(1);
また、接続文字列でMinPoolSizeを実験して、プールに常にいくつかの接続があるようにすることも価値があります。
SqlDataReaderは最速の方法です。パラメータとして序数を取る適切なGetxxxメソッドを使用して、その使用を最適化します。
十分に高速でない場合は、クエリを微調整できるかどうかを確認してください。取得する列にカバーインデックスを配置します。これにより、SQL Serverはインデックスを読み取るだけで済み、必要なすべての情報を取得するためにテーブルに直接アクセスする必要がありません。
行の1列を列の1行に変換し、1行のみを読み取るのはどうですか? SqlDataReader
には、単一の行を読み取るための最適化があります(System.Data.CommandBehavior.SingleRow
引数のExecuteReader
)。したがって、速度を少し改善できる可能性があります。
いくつかの利点があります。
reader[0]
)、reader
)を別の配列に複製する方が、要素をループして新しい配列に各要素を追加するよりも高速です。一方、SQLデータベースに強制的に多くの作業を行わせることには欠点があります。
速度に影響する可能性がある(データリーダー以外に)考慮すべき表面レベルの事項:
ただのランダムな考え。あなたの状況で何が役立つかわからない。
「SQL Serverデータベースから行の順方向専用ストリームを読み取る方法を提供します」これはMSDNのSqlDataReaderの使用です。 SqlDataRederの背後にあるデータ構造は、先読みのみを許可し、一方向のデータの読み取りに最適化されています。私の意見では、単純なデータの読み取りには、DataSetよりもSqlDataReaderを使用します。
4セットのオーバーヘッドがあります-ディスクアクセス-.netコード(cpu)-SQLサーバーコード(cpu)-マネージコードとアンマネージコードを切り替える時間(cpu)
まずは
select * where column = “junk”
唯一の解決策ではないにしても、ディスクを高速化することです。 (SQL Serverから読み取ることができるよりも速くデータを取得できます)
C#でSql Server関数を定義してから、列に対して関数を実行できる場合があります。申し訳ありませんが、方法がわかりません。これは、データリーダーよりも高速です。
CPUが複数あり、テーブルの中央に値があることがわかっている場合は、複数のスレッドを使用してみてください。
安全であることがわかっている区切り記号を使用して、すべての文字列を1つの文字列に結合するTSQLを作成できる場合があります。次に、C#で文字列を再度分割します。これにより、マネージコードとアンマネージコード間のラウンドトリップ回数が削減されます。
応答性が大量のデータの読み込みの問題である場合は、非同期メソッドの使用を確認してください-BeginReader。
アプリがレスポンシブであり続ける間、私はこれをバックグラウンドで大きなGUI要素を埋めるために常に使用します。
このデータの大きさ、またはすべてを配列にロードする理由を正確に述べていません。
多くの場合、大量のデータについては、データベースに残したり、データベースに手間をかけさせたい場合があります。ただし、一度に配列内ですべてを必要とする処理の種類を知る必要があります。