2011-08-12 11 views
1

私は多くのSQLの挿入/更新/削除ステートメントのいくつかは冗長です。PostgreSQL、MySQL - 冗長な更新/挿入/削除の最適化

1)

INSERT INTO "foo" ("id", ...) VALUES (123, ...) 
... 
DELETE FROM "foo" WHERE "id" = 123 

2)

INSERT INTO "foo" ("id", "col", ...) VALUES (123, 'value', ...) 
... 
UPDATE "foo" SET "col" = 'other value' WHERE "id" = 123 

3)

UPDATE "foo" SET "col" = 'value' WHERE "id" = 123 
... 
UPDATE "foo" SET "col" = 'other value' WHERE "id" = 123 

4)

DELETE FROM "foo" WHERE "id" = 123 
... 
INSERT INTO "foo" ("id", ...) VALUES (123, ...) 
:例えば私は冗長性、次の種類があるかもしれません

私はそこにある他の種類の冗長性について忘れているかもしれません。

  • 文がデータベースに送信され、

    • 文は、単一のトランザクションで実行し、そこSELECTクエリはありませんそれらの挿入/更新/削除文の間に実行しますことを考えるとデータベースによって解析され、一緒に実行される単一のAPI呼び出し

    これらの冗長性をデータベースに送信する前にそれらを削除しようとするとどのくらいの意味がありますか?つまり、PostgreSQL、MySQLなどのデータベースには、実際に実行する前に冗長コードを削除する仕組みがありますか?

    重要な免責事項:私は実行されている実際のSQLコードを制御できません。 ORM APIの周りにラッパーを記述すると、それらのステートメントを自動的に最適化する必要があります。しかし、これは難しいことです。外来キーやユニークな制約など、世話をするべきことがたくさんあります。明らかに、クライアント側での最適化は、データベースのパフォーマンスに良い影響を与えます。しかし、これは複雑な作業です。類似したアルゴリズムだけがすでにデータベースの最後で実行されている場合、私はむしろ彼らに仕事をさせるでしょう。

    ソリューション

    私は両方UNIQUEREFERENCES制約が遅延しているのPostgreSQL 9.0に切り替えます。それが保持されているデータベースの場合、1行のプリミティブ操作の任意のシーケンスをただ1回の操作(つまり... DELETE,INSERT->UPDATE)に圧縮することは可能です。もちろん、答えに記載されているように、これはトリガがないことを前提としています(私の場合です)。

  • 答えて

    2

    例では、最適化は行われません。データベースは指示どおりに動作します(INSERT最初はDELETE)。

    SQL ServerOracleサポートINSERTUPDATEDELETEを兼ね備えたが、それは現在PostgreSQLでもMySQLでもないサポートされているMERGEコマンド。

    MySQLは、特定のケースで役立つINSERT … ON DUPLICATE KEY UPDATEもサポートしています。

    +0

    したがって、リレーショナルデータベースはかなり低レベルのツールですが、それは私のようです。まあ、知っておいてよかった。 – julkiewicz

    +0

    問題の一部は、特にすべての行で発生するように設計されたトリガーなどを考慮した場合、これらの変更の一部は実際には冗長ではないということです。 また、マージはクエリを書き換えることができない限り、他のデータベースに対しても最適化を行うことができます。 また、一部のデータベースでは、上記のような場合に内部最適化が行われます(特に、単一のトランザクション内でこれらの変更をすべて実行できる場合)。 1つの例としてPostgres Heap-Only Tuplesの機能があります。これにより、あなたのプロセスのタイプでのディスク上のオーバーヘッドの一部が解消されます。 – xzilla

    関連する問題