1

問題

フラットファイルレコードを処理する複数の並列プロセスがあります。各ファイルは、電気通信システムの特定のインターフェイスに対応します(システムを通過するメッセージには、32桁のグローバル一意識別子が与えられ、複数のインターフェイスに特定のメッセージのレコードが存在する可能性があります)。各ファイルを処理するプロセスは1つあります。

インターフェイスをA、B、Cと呼びましょう。メッセージ文字列は、作成されたインターフェイスによって異なる場合があります。システムを通過する各メッセージに関する情報を格納するテーブルを作成することになっています。したがって、このテーブルには(他のフィールドの中でも)id、message_on_A、message_on_B、message_on_Cが含まれている必要があります。同じIDのエントリが重複しないようにしたいと思います。

私が試したことは次のとおりです。

  1. idをPRIMARYKEYとして設定し、INSERT ON DUPLICATE KEY UPDATEコマンドを使用して、各プロセスに対応するメッセージフィールドを設定します。
  2. idを複数の部分に分割し、これらの部分を複合主キーとして使用します。残りは1と同じです。
  3. すべてのレコードを保存し、2番目のクエリを使用して各IDのすべての情報を抽出します(GROUP BY ID、およびmax(message_on_A)、max(message_on_B)、max(message_on_C)を使用)。このアプローチに定義された主キーはありません。

これらのアプローチはどれも十分に高速ではありません。100万のIDで約30秒の実行時間を達成できるソリューションを探しています(つまり、3つのインターフェイスを考慮した300万のレコード)。

1番目と2番目のアプローチは、MyISAMテーブルで約400秒で作業を実行しました。InnoDBも試してみましたが、かなり遅くなりました。

現時点では、アプローチ3に別のショットを与えることを検討していますが、はるかに高速なクエリを見つける必要があります(GROUP BYおよびmax()クエリは終了する前に20分以上続きました)

質問:誰かがこの問題のためのより良いスキーマを提案できますか?そして、より良いクエリ?

4

2 に答える 2

2

私は3番目のアプローチの修正を考えています。GUIdを各テーブルの主キーとして、データを3つの別々のテーブルに格納します。これにより、挿入が可能な限り高速になります。このレベルで重複を処理します。

group byの代わりに、次のことを試してください。

select A.id,
       A.message as A_message,
       (select B.message from B where B.id = A.id limit 1) as B_message,
       (select C.message from C where C.id = A.id limit 1) as C_message
from A

これが機能する場合、唯一の問題はメッセージにAコンポーネントがない場合です。それを修正する方法もあると思います。問題は、これがパフォーマンスの目標を達成するかどうかです。

于 2012-08-28T15:31:16.010 に答える
1

innodbには多くの構成パラメーターがあります。このストレージエンジンは、並行環境ではるかに優れたパフォーマンスを発揮すると思います。mysqlのデフォルト設定は、最新のハードウェアには適していません。そのため、それらを調整してベンチマークを再実行することから始めてください。

于 2012-08-28T15:18:55.037 に答える