2

テーブルの何千もの行を更新する必要があります。たとえば、IDが-1、2..1000の1000行があります。

mytable:
| id   | value1 | value2 |
|  1   |  Null  |  Null  |
|  2   |  Null  |  Null  |
...
| 1000 |  Null  |  Null  |

次に、最初の10行を変更する必要があります。私はこのようにそれを行うことができます:

UPDATE mytable SET value1=42, value2=111 WHERE id=1
...
UPDATE mytable SET value1=42, value2=111 WHERE id=10

これには多くのリクエストが必要であり、それほど高速ではないため、この最適化を行うことにしました。

UPDATE mytable SET value1=42  WHERE id in (1, 2, 3.. 10)
UPDATE mytable SET value2=111 WHERE id in (1, 2, 3.. 10)

:この場合、実際に書き込むことはできますSET value1=42, value2=111が、実際のアプリケーションでは、このIDのセットは同じではありません。1つの行に対してvalue1を設定し、他の-value2に対して、行のサブセットに対して両方を設定する必要があります。そのため、2つのクエリが必要です。

問題は、IDが非常に多いことです。このクエリは約1Mbです!

Q1:これはこの更新を最適化する正しい方法ですか?

Q2:非常に大きなクエリを送信するのは正しいですか?このクエリをいくつかの小さな部分に分割することで、より高速な更新を取得できますか?

ステートメントを使用できませんwhere。プログラムに行IDがたくさんあります。

4

2 に答える 2

4

一時テーブルを作成し、ターゲットIDと新しい値を入力します。次に、UPDATE with FROM句を使用してそのターゲットに結合し、単一のコマンドで実行します。

一般に、このようなID /値が多数ある場合は、最初にそれらをデータベースに移動すると、作業が楽になります。

于 2012-12-14T09:05:53.507 に答える
1

Q1:これはこの更新を最適化する正しい方法ですか?

CASE ... WHEN構文構造を使用して、1つのクエリでそれを記述できるはずです。

UPDATE mytable SET
  value1 = 
    CASE 
      WHEN id IN ( 1, 2, 3, 10) THEN 42
      WHEN id IN (11,12,13, 20) THEN 43
      ELSE value1
    END,
  value2 =    
    CASE 
      WHEN id IN ( 1, 2, 3, 10) THEN 42
      WHEN id IN (11,12,13, 20) THEN 43
      ELSE value2
    END;

複数の場所で行を更新する必要があるかもしれないとおっしゃいましたが、上記では1つのクエリで問題なく更新できます。

更新:速度があなたの主な関心事であるという事実を見落としました(あなたは「最適化する」と言いました)、そして私の答えはその点で正しくありません。選択した回答で説明されているように一時テーブルを使用すると、パフォーマンスが大幅に向上します。

Q2:非常に大きなクエリを送信するのは正しいですか?このクエリをいくつかの小さな部分に分割することで、より高速な更新を取得できますか?

Postgresqlが大きなクエリ(1MBよりはるかに大きい)を処理するのに多くの問題があるべきではないと思います。SQLDB初期化スクリプトは1MBよりもはるかに大きくなる可能性があることに注意してください。

于 2012-12-14T10:13:02.963 に答える