【问题标题】:Using composite PRIMARY KEY or UNIQUE key on INNODB table with multiple inserts在具有多个插入的 INNODB 表上使用复合 PRIMARY KEY 或 UNIQUE 键
【发布时间】:2013-05-02 10:05:31
【问题描述】:

我一直在尝试解决这个问题,但到目前为止还没有运气。

哪个更好:具有复合 PRIMARY KEY 或单个 PRIMARY KEY 和 UNIQUE 索引的表?

我的桌子是这样的:

CREATE TABLE data (
  bucket_id INTEGER,
  backend_id INTEGER,
  unique_id INTEGER,
  weight INTEGER,
  PRIMARY KEY (bucket_id, unique_id)
) ENGINE=InnoDB

我正在做多个插入。 60 亿多行以

的形式插入到多值插入中
INSERT IGNORE INTO data VALUES (x1, x2, x3, x4), (y1, y2, y3, y4), .......)

每行有 500000 行(受客户端限制)。这些都是在应用程序启动时完成的,目前我需要尽可能加快速度。我需要(backend_id,unique_id)的唯一性。虽然我不控制这些,所以导入的数据中有重复。

所以问题是,使用 UNIQUE 索引而不是复合 PRIMARY KEY 会帮助我提高插入语句的速度吗?我知道很多其他因素会影响这一点,例如缓冲池等。

【问题讨论】:

  • “哪个更好:具有复合主键或单个主键和唯一索引的表?”“单个主键”是什么?
  • " 我需要 (backend_id, unique_id) 的唯一性。虽然我不控制这些,所以导入的数据中有重复。" 这是否意味着存在不良数据你需要修复还是忽略?
  • 单个 PRIMARY KEY 将是 bucket_id。不,数据还不错,但是数据的唯一性依赖于我需要导入的更多列,所以如果两行发生冲突,那么 backend_id 和 weight 将是相同的,所以忽略第二行是安全的。

标签: sql performance insert indexing innodb


【解决方案1】:

我很确定所有现代数据库管理系统中的主键约束都是使用唯一索引实现的。在 SQL 中,声明 PRIMARY KEYNOT NULL UNIQUE 在行为上是等效的。

您的问题归结为:在 {backend_id, unique_id} 的必要约束之外使用代理键是否更快?请注意,使用代理键代替对 {backend_id, unique_id} 的必要约束通常是不可接受的,因为它忽略了一个重要的业务需求。

添加代理键

  • 让桌子变宽,
  • 增加了必须写入表的字节数,并且
  • 增加了必须写入的索引数量。

因此,添加代理键可能会减慢您的速度。这可能是满足您所述要求的最佳结构如果您需要并发访问

CREATE TABLE data (
  backend_id INTEGER,
  unique_id INTEGER,
  weight INTEGER,
  PRIMARY KEY (backend_id, unique_id)
) ENGINE=InnoDB

但如果您基本上可以在单用户模式下运行,那么使用批量加载器加载具有no 约束的表是最快的。然后稍后使用ALTER TABLE 语句添加约束。

【讨论】:

  • 对不起,如果我不清楚,我很抱歉。但问题不在于 SQL 语法,而是在进行大量插入时,后者的建议是否更快。
  • @Moffe:更新了我的答案。
猜你喜欢
  • 2011-12-15
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 2011-04-20
  • 2021-11-11
相关资源
最近更新 更多