sql >> データベース >  >> RDS >> Mysql

MySQLでのSqlalchemyの一括更新は非常に遅く動作します

    データベースサーバー(あなたの場合のように)のレイテンシーが非常に悪い場合でも、トリックを使用して一括更新操作を高速化できます。テーブルを直接更新する代わりに、ステージテーブルを使用します 新しいデータを非常に高速に挿入するには、 destination-tableに対して1回のjoin-updateを実行します。 。これには、データベースに送信する必要のあるステートメントの数を大幅に減らすという利点もあります。

    これはUPDATEでどのように機能しますか?

    テーブルentriesがあるとします 常に新しいデータが届いていますが、更新したいのはすでに保存されているデータだけです。宛先テーブルentries_stageのコピーを作成します 関連するフィールドのみが含まれています:

    entries = Table('entries', metadata,
        Column('id', Integer, autoincrement=True, primary_key=True),
        Column('value', Unicode(64), nullable=False),
    )
    
    entries_stage = Table('entries_stage', metadata,
        Column('id', Integer, autoincrement=False, unique=True),
        Column('value', Unicode(64), nullable=False),
    )
    

    次に、一括挿入を使用してデータを挿入します。これは、SQLAlchemyでネイティブにサポートされていないが、それほど問題なく構築できるMySQLの複数値挿入構文を使用する場合にさらに高速化できます。

    INSERT INTO enries_stage (`id`, `value`)
    VALUES
    (1, 'string1'), (2, 'string2'), (3, 'string3'), ...;
    

    最後に、次のように、destination-tableの値をstage-tableの値で更新します。

     UPDATE entries e
     JOIN entries_stage es ON e.id = es.id
     SET e.value = es.value;
    

    これで完了です。

    インサートはどうですか?

    もちろん、これはインサートを高速化するためにも機能します。すでにステージテーブルにデータがあるので 、あなたがする必要があるのはINSERT INTO ... SELECTを発行することだけです destination-tableにないデータを含むステートメント まだ。

    INSERT INTO entries (id, value)
    SELECT FROM entries_stage es
    LEFT JOIN entries e ON e.id = es.id
    HAVING e.id IS NULL;
    

    これの良いところは、INSERT IGNOREを実行する必要がないことです。 、REPLACE またはON DUPLICATE KEY UPDATE何もしない場合でも主キーをインクリメントします




    1. SQL:BETWEENvs<=および>=

    2. php日時をmysqlデータベースに保存します

    3. SQL ServerでJOINを使用してUPDATEステートメントを実行するにはどうすればよいですか?

    4. 無効なPathExpression。 StateFieldPathExpressionである必要があります