どのようにパフォーマンスを最大化する?

どんなに頑張っても、私は周りを見回すことができないという問題があります。

この会社は市場分析に携わり、かなり大きなテーブル(300K〜1M行)とたくさんの列(250〜300と考える)を持っています。

私は問題に直ちにしようとします:

問題は、データのフィルタリングです。これまでに試したすべてのデータベースは、データを選択して返すのが遅すぎます。

現時点では、テーブル全体をメモリに格納し、動的LINQを使用してフィルタリングしています。

しかし、これはかなり高速ですが(250,000行をフィルタリングするのに約100ミリ秒)、これよりも良い結果が必要です...

私のコード(データモデルではない)で何かを変更してフィルタリングを高速化できる方法はありますか?

私は使ってみました:

DataTable.Selectは遅いです。動的LINQは良いですが、   まだ遅すぎる。ほとんどの(テスト目的のための)通常のLINQ   十分です。 MySQLからフェッチして後で処理する   それは悪いです。

このプロジェクトの冒頭で、私たちは高性能なデータベースでこれを処理できると考えましたが、私は試しました:

H2(IKVM) HSQLDB(コンパイルされたODBCドライバ) CubeSQL MySQL SQL SQLite ...

そして、彼らはすべて.NETにインターフェイスして結果を得るのが非常に遅いです。

私はまた、データをチャンクに分割し、実行時にそれらを結合して、フィルタリングを必要とするデータの総量をより小さくすることを試みました。

私はこれをもっと速くすることができるこの宇宙には何か方法がありますか?

前もって感謝します!

更新

私はこのデータベースを作成していないと付け加えたいだけです。

いくつかの図を追加するには、このような(visit_munic_nameがインデックスに登録されている)データベースクエリウィンドウ(SQLyog)で2フィールドの単純な選択を行うとします。

SELECT key1, key2 FROM table1 WHERE filter1 = filterValue1

225639行で125ミリ秒かかります。

なぜそんなに遅いのですか?私は2つの異なるボックスをテストしました。

もちろん、彼らは明らかに、sometingを変更する必要がありますか?

2
正直言って、それは本当にたくさんの行ではありません。データベース構造のような私には、いくつかの重大な注意が必要です。
追加された 著者 Andrew Barber,
使用したすべてのデータベースでデータの選択が遅いと言います。これは私の心の中にいくつかの赤い旗を浮かべます。あなたの選択に複雑な結合をしていますか?どこに複雑な句がありますか?データベースは正しく索引付けされていますか?
追加された 著者 CadentOrange,
フィルタリングしている列がインデックスに登録されていないか、インデックスが断片化している可能性があります。これは、DBCC SHOWCONTIGコマンドを実行することで確認できます。 DBCC SHOWCONTIG( 'tablename')を開始点として試してみます。他のオプションについては、 bit.ly/AsNWRE を参照してください。
追加された 著者 CadentOrange,
ほとんどのデータベースでは、1M行は小さなデータセットです。
追加された 著者 Panagiotis Kanavos,
それではインデックスはどうですか?それはフィルタの列をカバーしていますか?フィルター列が索引の最初の列か、またはXX列の索引を1つ作成しましたか?最初の列がフィルターであり、選択値を含む索引を照会することは測定可能ではありません。フィルターが多数のレコードを戻さない限り、データベースを本当に非難することはできません。クエリで返されるレコードの数はいくつですか?あなたの質問は可能な限り選択的でなければなりません。さもなければデータベースの使用にあまり意味がありません
追加された 著者 Panagiotis Kanavos,
リレーショナルデータベースは、合計、中央値、平均などの単純な集計を実行するのに非常に優れているので、すべてのデータを返す必要はありません。分析データベースは実際にはそれらの集計を事前に計算しておくため、計算する必要はありません。オープンソースソフトウェアの使用を主張する場合は、MySQLの上でMondrianのようなOLAP製品を使用することができます。個人的に私は、SQL Serverとキューブを使用してはるかに大きなデータマートを作成し、認識可能な遅延なしにExcelピボットテーブルでアドホックな処理を可能にしました。これはサーバー自体ではなく、スタースキーマとキューブを使用しているため、高速なクエリが可能です
追加された 著者 Panagiotis Kanavos,
あなたは、DB側でDBネットワークリクエストそのものやSQLクエリの実行を利用するときに、何が遅いかを確認しましたか?ネットワークの要求/応答が遅い場合は、アプリケーションの近くでDBをホストできるかどうかを確認してください。そうでない場合は、SQLクエリのeprformanceやテーブルのインデックスなどを調整してください
追加された 著者 sll,
あなたがSSDをあなたの箱に差し込むことができればもっと速くする必要があるのであれば、私には非常に大きなデータベースとしては聞こえません。列数により、列指向のデータベースの候補になる可能性があります。これはディスクにデータを別々に保存するため、DBのスピードアップにつながります。
追加された 著者 gjvdkamp,
アンドリューバーバー、まさに!だから私はなぜクエリが遅いのだろうかと思います。もちろん、索引付けを行うとパフォーマンスが向上します。 sll、我々はより正確なものをより正確に測定しようとしました、我々はこれを続けます。 @CadentOrange、結合なし、filter1 = filterValue1のtable1からselect key1、key2、key3のように1つのフィルタを持つ1つのテーブル。普通のもの。 gjvdkamp、我々は現在、16 GBのRAMを搭載し、メモリ内のすべてをロードするHyper-V 2x2.4 GHzを使用しています。 PanagiotisKanavos、本当です。
追加された 著者 Johan,
@PanagiotisKanavos、あなたのコメントありがとう。フィルタリングは速いかもしれませんが、データも返さなければなりません:)基本的には、最終的にはデータ(sum、medianなど)の計算が行われますが、残念ながらMySQL/H2/HSQLDBは​​かなり遅いですこれは私がテストしたときにHSQLDBが最高でした。だから、私は非常に速い記憶でこれをしなければなりません。しかし、データそのものが戻ってくるまでには数ミリ秒かかる場合は、それは難しいです。
追加された 著者 Johan,
@PanagiotisKanavosは、実際には、私たちが行った測定では凝集体があまり良くありません。 LINQはあらゆる面ではるかに高速です。カスタムコンパイルされたメジアン関数を持つHSQLDBだけがパフォーマンスに近くなります。
追加された 著者 Johan,
@ PanagiotisKanavos、あなたは "フィルターが大量のレコードを返さない限り、あなたは本当にデータベースを責めることはできません。"では、だれが私を責めるべきですか?行を返さなければならないのですか?たとえ私がSQLyogのようなクエリを実行しても、selectに遅延があります。私たちが必要とする性能に達していた唯一のデータベースはH2とHSQLDBでしたが、テストしたときにH2が同時に多くの要求を処理できなかったため、このケースではHSQLDBが勝者となりました。しかし、H2は他のいくつかのもので速かったですが。
追加された 著者 Johan,

1 答え

正確に何をしたいか、多くの行をフィルタリングすることが重要である理由については説明していません。あなたのデータベースがあなたのために集計を事前に計算することができる場合、1M行をフィルタリングして集計を取得することがどれほど速くなければならないのですか?いずれにしても、あなたは仕事に間違ったツールを使用しているようです。

On one hand, 1M rows is a small number of rows for most databases. As long as you have the proper indexes, querying shouldn't be a big problem. I suspect that either you do not have indexes on your query columns or you want to perform ad-hoc queries on non-indexed columns.

さらに、データスキーマが間違っている場合は、どのデータベースを使用しても問題ありません。分析アプリケーションでは、通常、スタースキーマを使用して、記述するよりもはるかに多くのデータをより高速に照会できます。

分析目的で使用されるすべてのデータベースは、データを好きな形に変換する必要がある特殊なデータ構造を使用します。 典型的なリレーショナルデータベースでは、集計を事前に計算するためにキューブと結合されたスタースキーマを作成する必要があります。 列データベースは、通常、高速の分析クエリを実現するために圧縮と組み合わせた列形式でデータを格納しますが、多くの人が慣れ親しんでいるSQL言語とは大きく異なる可能性がある独自の言語でクエリを学習する必要があります。

On the other hand, the way you query (LINQ or DataTable.Select or whatever) has minimal effect on performance. Picking the proper data structure is much more important.

For instance, using a Dictionary<> is much faster than using any of the techniques you mentioned. A dictionary essentially checks for single values in memory. Executing DataTable.Select without indexes, using LINQ to Datasets or to Objects is essentially the same as scanning all entries of an array or a List<> for a specific value,because that is what all these methods do - scan an entire list sequentially.

さまざまなLINQプロバイダは、データベースの仕事をしません。彼らはあなたの質問を最適化しません。彼らは実行するように指示した内容を実行します。並べ替えられたリストでバイナリ検索を行っても、一般的なLINQプロバイダを使用するよりも高速です。

あなたが何をする必要があるかによって、試してみることができるさまざまなものがあります:

  • データを素早く切り抜く方法をお探しの場合は、Excel 2010のPowerPivot機能などの既存製品を使用してください。PowerPivotは、数百万行をメモリ内の列形式でロードおよび圧縮し、データをピボットテーブルと同じように扱い、他のメモリソースとの結合を定義することさえできます。
  • より反復可能なプロセスが必要な場合は、リレーショナルデータベースに適切なスタースキーマを作成するか、カラムデータベースを使用します。どちらの場合でも、データを適切な構造にロードするためにスクリプトを記述する必要があります。

  • 独自のアプリケーションを作成する場合は、他の類似ツールで使用されているさまざまなアルゴリズムや構造を、

5
追加された