1

perl 経由で更新しようとしている大規模なデータベースがあります。追加する情報は、私が管理していない csv ファイルから取得されます (ただし、これは信頼できるものであり、当社の別の部門からのものです)。ファイル内の各レコードに対して、それを追加する (存在しない場合) か、何もしない (存在する場合) 必要があります。レコードの追加は通常の で構成されますINSERT INTOが、特定のエントリに対して実行する前に、特定の をUPDATE実行する必要があります。

具体的に言うと、ファイルには 10,000 のエントリがあり、そのうちの 90% は既にデータベースにあるとします。レコードをインポートする最も効率的な方法は何ですか? いくつかの明白なアプローチを見ることができます:

  • このタイプのすべてのレコードをデータベースから取得し、ファイルの各エントリのメンバーシップを確認します。欠点: 大量のデータ転送が発生し、サーバーがタイムアウトする可能性があります。
  • ファイルからエントリを読み込み、クエリを使用してそれらのレコードのみをRLIKE 'foo|bar|baz|...'クエリします (またはstuff = 'foo' || stuff = 'bar' || ...クエリですが、それはさらに悪いようです)。欠点: 巨大なクエリで、おそらくサーバーを停止させるのに十分です。
  • ファイルを読み込み、エントリごとにクエリを送信し、必要に応じて追加します。欠点: 何万ものクエリがあり、非常に遅い。

要件は別としてUPDATE、これはおそらく標準的な解決策があるかなり標準的な問題のようです。ある場合は、auto_increment主キーのテストを適切に使用することで、おそらく私のケースに適応させることができます。

4

2 に答える 2

1

標準的な解決策はINSERT IGNORE、制約のために挿入が失敗した場合にエラーを発生させない which を使用することです。UPDATEが機能することを知る前に、これを行う機会が与えられないため、これはあまり役に立ちませんINSERT。ただし、後で更新できる場合は、これが理想的です。INSERT IGNORE各レコードのみを実行し、UPDATE成功した場合は実行します。

レコードが既に存在する場合は、一致する一意のキーを持つレコードがデータベースに既に存在するRLIKEことを意味するため、遅くなるはずの提案がわかりません。

Perl を使用してSELECT count(*) FROM table WHERE key = ?、各レコードを使用して CSV ファイルを grep し、結果がゼロ以外のものをすべて削除します。

次に、フィルタリングされた CSV データに残っているすべてに対してUPDATEandを実行します。INSERT

于 2012-05-29T21:13:48.207 に答える
0

リストの反復中にデータをフラッシュし続ける場合、サーバーをタイムアウトにする必要はありません。

于 2012-05-29T21:09:59.173 に答える