2016-07-02 5 views
0

私たちはHerokuのライブPostgresデータベースを作成しています。正規表現を使用して複数の文字列を置き換えて約500万行を更新する必要があります。これは合計で約1億回の更新を実行することを意味します。ライブデータベースの更新前のインデックスの削除

我々はそれをこのように更新されています(使用してpsycopg2)

for element in list: 
    cursor.execute("Update table set text = regexp_replace(text, %s, 'NewWord', 'gi') where date >= '2017-12-31';", [element]) 

データベースは、ライブと私たちのDjangoのウェブサイトにリンクされている、と私たちは、データベースへのこの更新プログラムを必要とし、3日以内に新しい機能をロールバックする必要があります。 Postgresガイドは、インデックスを削除するとはるかに高速だと言っていますが、外部キーインデックスを削除すると、Googleのdjangoの機能が停止し、ウェブサイトがダウンする可能性があります。それでも、私たちは週末には1日から2日間、面倒を見ることができますが、それ以上のことはありません。

ので:

  1. は、インデックスを削除することで、億回の 更新が一日で行うことができると仮定することは安全ですか?
  2. もしそうなら、プライマリ キーインデックスも削除する必要がありますか?
  3. もしそうでなければ、インデックスを削除せずに、同じような のアップデートを実行するまでにどれくらい時間がかかりますか?
+0

モデルを使用してレコードを更新するだけでDjango ORM(またはSQLAlchemyを使用する場合)に頼る方が安全ではないでしょうか? Django(DjangoシェルまたはDjango Admin)以外のスキーマを変更すると、データに矛盾が生じる可能性があるため、一般的にはお勧めしません。 – dmitryro

+0

これは、ポストグレスの質問よりもHerokuの質問によく似ています。なぜなら、答えの多くはハードウェアと構成に依存しているからです。それで、ベンチマークとして10kアップデートを発行しようとしましたか? – jmelesky

+1

また、各行を20倍に更新するとテーブルが膨らんでしまいます(postgresはすべての更新に対して行のコピーを作成し、それらのコピーはバキューム処理でのみクリーンアップされます)。とりわけ、更新が進むにつれて更新がより長くかかる可能性があることを意味します。行ごとに1つの更新に減らすことができれば、それは間違いなくあなたを助けます。 – jmelesky

答えて

0
  1. 1時間以内に1億回の更新が可能です。 (行サイズが大きすぎない場合)
  2. いいえ、主キーはテキストフィールドの更新の影響を受けませんので、そのままにしてください。
  3. 更新に必要な時間は、インデックス(影響を受けたテキストフィールドにインデックスがない場合)

クエリ(単純化のために、私はパラメータ化を除去し、{ztable、ZDATE、ztext}で{テーブル、日付、テキストを}に置き換え、キーワードなので):

Update ztable 
set ztext = regexp_replace(ztext, 'Oldword', 'NewWord', 'gi') 
where zdate >= '2017-12-31'; 

はのように、WHERE句に特別な条件を追加することで多くのことを高速化することができる:これは、更新が実際の行には何もしない場合に作成されるように、余分な行のバージョンを回避します

Update ztable 
set ztext = regexp_replace(ztext, 'Oldword', 'NewWord', 'gi') 
where zdate >= '2017-12-31' 
AND ztext LIKE '%Oldword%' 
; 

。 (行が実際に変更された場合、更新はI/O +約3回のI/Oを必要とします)

余分なメモ:インデックスがある場合ztext列に:それを投げ捨てる;おそらく役に立たないでしょう。 フロントエンドのループを削除し、すべてのロジックをUPDATEに入れると、余分なパフォーマンスが得られるかもしれません。

関連する問題