43

C#を使用して、SQLServerのテーブルからメモリ内の配列に文字列の1列をロードする必要があります。SqlDataReaderを開いてループするよりも速い方法はありますか?テーブルは大きく、時間が重要です。

編集私は.dllを構築し、データベースでのいくつかの操作のためにサーバー上でそれを使用しようとしています。しかし、今のところ遅くなります。これが最速の場合は、データベースを再設計する必要があります。私は物事をスピードアップする方法があるかもしれないと思います。

4

11 に答える 11

56

データリーダー

SQLにアクセスする最速のアクセスについては、SqlDataReaderを使用します。

プロファイルする

パフォーマンスの問題がどこにあるかを実際にプロファイリングする価値があります。通常、パフォーマンスの問題があると思われる場合は、プロファイルを作成した後、完全に間違っていることが証明されます。

たとえば、次のようになります。

  1. 時間...クエリの実行にかかる時間
  2. 時間...データがネットワーク/プロセス境界を越えてコピーするのにかかる時間
  3. 時間....Netがデータをメモリにロードするのにかかる時間
  4. 時間...あなたのコードはそれで何かをするのにかかります

これらのそれぞれを個別にプロファイリングすると、ボトルネックがどこにあるかをより正確に把握できます。コードのプロファイリングについては、Microsoftからのすばらしい記事があります

キャッシュする

パフォーマンスを向上させるために注目すべきことは、そのすべてのデータを毎回ロードする必要があるかどうかを判断することです。リスト(またはその一部)をキャッシュできますか?新しいSystem.Runtime.Caching名前空間を見てください。

T-SQLとして書き直します

純粋にデータ操作を行っている場合(質問が示唆しているように)、データを使用するコードをT-SQLに書き直して、SQLでネイティブに実行することができます。これは、データを直接操作し、データをシフトしないため、はるかに高速になる可能性があります。

コードに必要な手続き型ロジックがたくさんある場合は、T-SQLとCLR統合を組み合わせて、両方の利点を活用してみてください。

これは、ロジックの複雑さ(またはより手続き的な性質)に大きく依存します。

他のすべてが失敗した場合

すべての領域が最適(またはほぼ)であり、設計に問題がない場合。私はマイクロ最適化にさえ入りません、私はそれにハードウェアを投げるだけです。

どのハードウェアですか?信頼性とパフォーマンスのモニターを試して、ボトルネックがどこにあるかを調べてください。HDDまたはRAMについて説明する問題が発生する可能性が最も高い場所です。

于 2010-09-16T11:31:47.947 に答える
19

速度が十分でない場合SqlDataReaderは、(メモリ内の)キャッシュなど、他の場所にデータを保存する必要があります。

于 2010-09-16T11:26:51.730 に答える
18

いいえ。これは実際には最速の方法であるだけでなく、唯一の(!)方法です。他のすべてのメカニズムは、とにかく内部的にDataReaderを使用します。

于 2010-09-16T11:23:19.060 に答える
8

私はそれSqlDataReaderがあなたが得ようとしているのとほぼ同じくらい良いと思います。

于 2010-09-16T11:18:44.833 に答える
5

SqlDataReaderが最速の方法です。列名で取得するのではなく、必ず序数で取得するメソッドを使用してください。例:GetString(1);

また、接続文字列でMinPoolSizeを試して、プール内に常にいくつかの接続があるようにすることも価値があります。

于 2010-09-16T11:37:37.783 に答える
3

SqlDataReaderが最速の方法になります。パラメータとして序数をとる適切なGetxxxメソッドを使用して、その使用を最適化します。

速度が十分でない場合は、クエリを微調整できるかどうかを確認してください。取得する列にカバーインデックスを付けます。そうすることで、SQL Serverはインデックスを読み取るだけでよく、必要なすべての情報を取得するためにテーブルに直接移動する必要はありません。

于 2010-09-16T12:07:20.757 に答える
2

1列の行を1行の列に変換し、読み取る行が1つしかない場合はどうでしょうか。SqlDataReaderは単一行(System.Data.CommandBehavior.SingleRowの引数ExecuteReader)を読み取るための最適化を備えているため、速度を少し向上させることができるかもしれません。

いくつかの利点があります。

  • 単一行の改善、
  • 反復ごとに配列にアクセスする必要はありません(reader[0])、
  • 配列(reader)を別の配列に複製する方が、要素をループして各要素を新しい配列に追加するよりも高速な場合があります。

一方、SQLデータベースにさらに多くの作業を強制することには欠点があります。

于 2010-09-16T11:30:01.660 に答える
1

「SQLServerデータベースから行の順方向のみのストリームを読み取る方法を提供します」これは、MSDNのSqlDataReaderの使用法です。SqlDataRederの背後にあるデータ構造は、前方への読み取りのみを許可し、一方向のデータの読み取り用に最適化されています。私の意見では、単純なデータ読み取りには、DataSetよりもSqlDataReaderを使用したいと思います。

于 2010-09-16T11:34:39.297 に答える
1

4セットのオーバーヘッドがあります-ディスクアクセス-.netコード(cpu)-SQLサーバーコード(cpu)-マネージドコードとアンマネージドコード(cpu)を切り替える時間

まずは

select * where column = “junk” 

唯一の解決策がディスクを高速化することではないにしても、十分に高速です。(SQL Serverからデータを読み取るよりも速く取得できます)

C#でSQL Server関数を定義してから、列に対して関数を実行できる場合があります。すみません、やり方がわかりません。これは、データリーダーよりも高速な場合があります。

複数のCPUがあり、テーブルの中央の値がわかっている場合は、複数のスレッドを使用してみることができます。

安全であることがわかっているセパレータを使用して、すべての文字列を1つの文字列に結合するTSQLを記述できる場合があります。次に、文字列をC#で再度分割します。これにより、マネージコードとアンマネージコード間のラウンドトリップの数が減ります。

于 2010-09-16T14:44:32.580 に答える
1

速度に影響を与える可能性のあるいくつかの表面レベルの考慮事項(データリーダー以外):

  1. データベースクエリの最適化
    • OrderByは高価です
    • Distinctは高価です
    • RowCountは高価です
    • GroupByは高価です
    • など。これらがないと生きていけないこともありますが、代わりにC#コードでこれらのいくつかを処理できる場合は、より高速になる可能性があります。
  2. データベーステーブルのインデックス付け(最初に、WHERE句のフィールドにインデックスが付けられていますか?)
  3. データベーステーブルのデータ型(データを考慮して、可能な限り最小のものを使用していますか?)
  4. なぜデータリーダーを配列に変換するのですか?
    • たとえば、配列に変換する必要のないアダプタ/データテーブルを作成することも同様に役立ちますか?
  5. Entity Frameworkを調べましたか?(遅くなる可能性があります...しかし、オプションがない場合は、確認するためだけに調べる価値があるかもしれません)

ただランダムな考え。あなたの状況で何が役立つかわからない。

于 2010-09-16T18:39:28.977 に答える
0

応答性が大量のデータをロードする際の問題である場合は、非同期メソッド(BeginReader)の使用を検討してください。

アプリが応答し続けている間、バックグラウンドで大きなGUI要素を設定するためにこれを常に使用します。

このデータの大きさや、すべてを配列にロードする理由については、正確には説明していません。

多くの場合、大量のデータについては、データベースに残しておくか、データベースに手間のかかる作業を任せたい場合があります。ただし、一度にすべてを配列で処理する必要がある、実行している処理の種類を知る必要があります。

于 2010-09-16T13:25:32.753 に答える