【问题标题】:PostgreSQL, MySQL - redundant update/insert/delete optimizationPostgreSQL、MySQL - 冗余更新/插入/删除优化
【发布时间】: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,其中 UNIQUEREFERENCES 约束都是可延迟的。在一个数据库的情况下,可以将一行上的任意原始操作序列压缩为单个操作(即...,DELETEINSERT -> UPDATE)。当然,正如答案中提到的,这假设没有触发器(这是我的情况)。

【问题讨论】:

    标签: sql database postgresql optimization orm


    【解决方案1】:

    在您的示例中,不会进行任何优化,数据库将完全按照指示运行(首先是INSERT,然后是DELETE)。

    SQL ServerOracle 支持组合 INSERTUPDATEDELETEMERGE 命令,但目前PostgreSQLMySQL 均不支持。

    MySQL 还支持INSERT … ON DUPLICATE KEY UPDATE,这在某些情况下会有所帮助。

    【讨论】:

    • 所以在我看来,关系数据库在某种程度上是一个相当低级的工具。好吧,很高兴知道。
    • 您的部分问题是其中一些更改并不是真正多余的,特别是如果您考虑到可能设计为在每一行上触发的触发器之类的东西。此外,除非您可以重写查询,否则合并并没有真正的帮助,在这种情况下,您也可以对其他数据库进行一些优化。此外,某些数据库确实针对上述情况进行了内部优化,特别是如果您可以在单个事务中完成所有这些更改。一个例子是 Postgres Heap-Only Tuples 功能,它将消除您的进程类型中的一些磁盘开销。
    猜你喜欢
    • 2014-08-27
    • 2016-10-16
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多