我有很多 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
查询运行, - 语句在单个事务中运行,
- 语句通过单个 API 调用发送到数据库,由数据库解析并一起执行
在将它们发送到数据库之前尝试删除这些冗余有多大意义?换句话说,像 PostgreSQL、MySQL 这样的数据库是否有机制在实际运行之前自行删除冗余代码?
重要免责声明:我无法控制正在运行的实际 SQL 代码。我围绕 ORM API 编写了一个包装器,它必须自动优化这些语句。然而这很难——有很多事情需要处理,例如外键和唯一约束。显然,客户端的任何优化都会对数据库性能产生积极影响。然而,这是一项复杂的任务,如果只有类似的算法已经在数据库端运行,我宁愿让它们来完成这项工作。
解决方案
我切换到 PostgreSQL 9.0,其中 UNIQUE
和 REFERENCES
约束都是可延迟的。在数据库的情况下,可以将一行上的任意原始操作序列压缩为单个操作(即 ...,DELETE
, INSERT
-> 更新
)。当然,正如答案中提到的,这假设没有触发器(这是我的情况)。
最佳答案
在您的示例中,不会进行任何优化,数据库将完全按照指示运行(首先是INSERT
,然后是DELETE
)。
SQL Server
和 Oracle
支持 MERGE
命令,它结合了 INSERT
, UPDATE
和 DELETE
,但目前 PostgreSQL
和 MySQL
均不支持。
MySQL
还支持 INSERT … ON DUPLICATE KEY UPDATE
,这在某些情况下会有所帮助。
关于sql - PostgreSQL、MySQL——冗余更新/插入/删除优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7042676/