【问题标题】:SQL performance impact on multiple columns in constraint or unique indexSQL 性能对约束或唯一索引中的多个列的影响
【发布时间】:2021-01-14 06:01:31
【问题描述】:

我在 postgres 中创建了一个表,其中包含基于从 csv 导入的各种列。由于可以通过一些更改重新上传 csv,并且我不希望重新上传在未更改的行上创建重复项,因此我添加了一个约束和唯一索引,其中包含大多数列。这样做有任何性能问题吗?有没有更好的方法来解决这个问题?

CREATE TABLE IF NOT EXISTS table_a (
    id SERIAL PRIMARY KEY,
    table_b_id SERIAL REFERENCES table_b(id) ON DELETE CASCADE,
    column_a INT,
    column_b INT,
    column_c BOOLEAN,
    created_time BIGINT NOT NULL,
    CONSTRAINT "table_a_key" UNIQUE ("table_b_id", "column_a", "column_b", "column_c")
);

【问题讨论】:

  • 与您的问题无关,但是:外键列永远不应定义为serial,这没有任何意义。 serial 只是 integer not null default nextval('some_seq') 的简写(“宏”) - 为什么要从外键列的序列中获取默认值?
  • @a_horse_with_no_name - 感谢您指出这一点,所以 table_b_id 实际上应该是 int 吗?我只是保持它与 table_b 中列 id 的类型相同
  • 是的,table_b_id 应该是int,它与引用的表相同的类型。如果您改用更现代的 identity 列,这会更明显。

标签: sql postgresql performance


【解决方案1】:

添加索引总是会给 INSERT、UPDATE 和 DELETE 语句带来性能损失,因为需要维护索引。

但是,在大多数情况下,增加的开销并不重要,并且可能会被 SELECTing 数据时改进的性能所抵消。与单行操作相比,执行批量加载时性能开销更明显。

但如果你想防止重复,你别无选择。

防止重复的唯一可靠方法是像您一样创建唯一约束(或索引)。这也是您使用 insert ... on conflict ... 使用“upsert”的唯一方法

所以,是的,需要支付性能损失。不,没有更好的方法来确保唯一性。

【讨论】:

  • 如果更新表上的列b,该表在列a 上有索引,索引是否会产生开销?同样,如果使用NULL 值插入索引列,这是否会导致性能损失?
猜你喜欢
  • 1970-01-01
  • 2019-10-16
  • 1970-01-01
  • 2023-03-11
  • 2018-12-02
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 2010-12-22
相关资源
最近更新 更多