2016-10-09 3 views
0

のは、あなたがこの定義を持つテーブルを持っている想像してみましょう:なぜMySQL InnoDBが同時更新を処理でき、PostgreSQLで処理できないのですか?

CREATE TABLE public.positions 
(
    id serial, 
    latitude numeric(18,12), 
    longitude numeric(18,12), 
    updated_at timestamp without time zone 
) 

そして、あなたは、このようなテーブル内の50,000行を持っています。今テスト目的のためにあなたは、このようなアップデートを実行します:あなたは30の異なるスレッド、MySQLのInnoDB内で、このようなクエリを実行する場合文が(この特定のデータセット内)50,000

から1,000行を更新します

update positions 
set updated_at = now() 
where latitude between 234.12 and 235.00; 

を成功し、ポストグルは多くのデッドロックで失敗します。

なぜですか?

答えて

3

普通の幸運、私は言うでしょう。

スレッドが30個先に進んで同じ1000行を更新したい場合は、同じ順序でこれらの行にアクセスすることができます(この場合、相互にロックアウトして順番に実行します)。ケースがデッドロックするケース)。

これはInnoDBとPostgreSQLで同じです。

あなたのケースで状況が異なる理由を分析するには、実行計画を比較することから始めます。たぶん、PostgreSQLが同じ順序ですべての行にアクセスしない理由を知ることができます。今ディスクを共有することができます

  • 同時に行われる大規模なシーケンススキャン読み取り(ジェフ・デイビス)

    この情報を欠いている、私はあなたが、同時シーケンシャルスキャンをスピードアップfeature introduced in version 8.3を経験していることを推測したいです

    これは、テーブルの途中で新しいシーケンシャルスキャンを開始し(別のシーケンシャルスキャンがすでに進行中の場合)、最初から最後まで折り返して実行されます。これは、ORDER BYを指定しないクエリで返される行の順序に影響します。コンフィグレーションパラメータsynchronize_seqscansを使用して、必要に応じてこれを無効にすることができます。

チェックは、あなたのPostgreSQLの実行計画は、シーケンシャルスキャンを使用し、synchronize_seqscansを変更すると、デッドロックを回避できるかどうかを確認します。

+0

あなたは正しいです。あなたはこれをポストグルで解決することができます:UPDATE .... WHERE id in(SELECT ... FROM ... WHERE ... id UP UPDATEによる順序)。 – SDReyes

+0

私は、*正しい*解決策は、* 30 *スレッドが同じ行を更新することではないと思う。私たちはDBを強調していない限り、 –

+0

です。これはベンチマークの一部なので、われわれは私たちです。 xD – SDReyes

関連する問題