我有很多SQL插入/更新/删除语句,其中一些是冗余的。例如,我可能有以下类型的冗余:
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
查询,在将这些冗余发送到数据库之前尝试删除这些冗余有多大意义?换句话说,像PostgreSQL,MySQL这样的数据库是否有机制在实际运行之前自行删除冗余代码?
重要免责声明:我无法控制正在运行的实际SQL代码。我编写了一个围绕ORM API的包装器,它必须自动优化这些语句。然而,这很难 - 有很多事情要处理,例如外键和唯一约束。显然,客户端的任何优化都会对数据库性能产生积极影响。然而,这是一项复杂的任务,如果只有类似的算法已在数据库端运行,我宁愿让他们完成这项工作。
解决方案
我切换到PostgreSQL 9.0,其中UNIQUE
和REFERENCES
约束都可以推迟。如果数据库存在,则可以将一行上的任意基本操作序列压缩为单个操作(即......,DELETE
,INSERT
- > {{1} })。当然正如答案中所提到的,假设没有触发器(这是我的情况)。
答案 0 :(得分:2)
在您的示例中,没有进行优化,数据库的行为与指示完全相同(先INSERT
然后DELETE
)。
SQL Server
和Oracle
支持MERGE
命令,它结合了INSERT
,UPDATE
和DELETE
,但PostgreSQL
目前不支持MySQL
1}}也不是MySQL
。
INSERT … ON DUPLICATE KEY UPDATE
也支持{{1}},在某些情况下可以提供帮助。