C#を使用して、SQLServerのテーブルからメモリ内の配列に文字列の1列をロードする必要があります。SqlDataReaderを開いてループするよりも速い方法はありますか?テーブルは大きく、時間が重要です。
編集私は.dllを構築し、データベースでのいくつかの操作のためにサーバー上でそれを使用しようとしています。しかし、今のところ遅くなります。これが最速の場合は、データベースを再設計する必要があります。私は物事をスピードアップする方法があるかもしれないと思います。
C#を使用して、SQLServerのテーブルからメモリ内の配列に文字列の1列をロードする必要があります。SqlDataReaderを開いてループするよりも速い方法はありますか?テーブルは大きく、時間が重要です。
編集私は.dllを構築し、データベースでのいくつかの操作のためにサーバー上でそれを使用しようとしています。しかし、今のところ遅くなります。これが最速の場合は、データベースを再設計する必要があります。私は物事をスピードアップする方法があるかもしれないと思います。
データリーダー
SQLにアクセスする最速のアクセスについては、SqlDataReaderを使用します。
プロファイルする
パフォーマンスの問題がどこにあるかを実際にプロファイリングする価値があります。通常、パフォーマンスの問題があると思われる場合は、プロファイルを作成した後、完全に間違っていることが証明されます。
たとえば、次のようになります。
これらのそれぞれを個別にプロファイリングすると、ボトルネックがどこにあるかをより正確に把握できます。コードのプロファイリングについては、Microsoftからのすばらしい記事があります
キャッシュする
パフォーマンスを向上させるために注目すべきことは、そのすべてのデータを毎回ロードする必要があるかどうかを判断することです。リスト(またはその一部)をキャッシュできますか?新しいSystem.Runtime.Caching名前空間を見てください。
T-SQLとして書き直します
純粋にデータ操作を行っている場合(質問が示唆しているように)、データを使用するコードをT-SQLに書き直して、SQLでネイティブに実行することができます。これは、データを直接操作し、データをシフトしないため、はるかに高速になる可能性があります。
コードに必要な手続き型ロジックがたくさんある場合は、T-SQLとCLR統合を組み合わせて、両方の利点を活用してみてください。
これは、ロジックの複雑さ(またはより手続き的な性質)に大きく依存します。
他のすべてが失敗した場合
すべての領域が最適(またはほぼ)であり、設計に問題がない場合。私はマイクロ最適化にさえ入りません、私はそれにハードウェアを投げるだけです。
どのハードウェアですか?信頼性とパフォーマンスのモニターを試して、ボトルネックがどこにあるかを調べてください。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データベースにさらに多くの作業を強制することには欠点があります。
「SQLServerデータベースから行の順方向のみのストリームを読み取る方法を提供します」これは、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要素を設定するためにこれを常に使用します。
このデータの大きさや、すべてを配列にロードする理由については、正確には説明していません。
多くの場合、大量のデータについては、データベースに残しておくか、データベースに手間のかかる作業を任せたい場合があります。ただし、一度にすべてを配列で処理する必要がある、実行している処理の種類を知る必要があります。