【发布时间】:2011-10-25 22:34:15
【问题描述】:
我有很多 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 -> UPDATE)。当然,正如答案中提到的,这假设没有触发器(这是我的情况)。
【问题讨论】:
标签: sql database postgresql optimization orm