MyISAM vs InnoDB 用于快速插入和复合唯一键



上下文:我正在创建一个多线程应用程序,该应用程序将非常频繁地插入/更新行。

最初我有下表:

#TABLE 1
CREATE TABLE `example` (
  `id` BIGINT(20) NOT NULL,
  `state` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`, `state`))
ENGINE = MyISAM;

但是,在进行了一些研究之后,我发现MySQL对MyISAM表使用表级锁定,一次只允许一个会话更新这些表(来源)。不适合频繁更改表的多线程应用程序。

因此,有人建议我从复合主键切换到自动生成的主键,该主键具有 id/state 的唯一索引。这将允许快速插入,同时仍然强制执行 id/状态的唯一组合。

#TABLE 2
CREATE TABLE `example` (
  `key` BIGINT(20) NOT NULL,
  `id` BIGINT(20) NOT NULL,
  `state` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`key`),
  UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC))
ENGINE = MyISAM;

但是,InnoDB 避免了表锁,而是使用行级锁定(源),因此我想切换到以下内容:

#TABLE 3
CREATE TABLE `example` (
  `key` BIGINT(20) NOT NULL,
  `id` BIGINT(20) NOT NULL,
  `state` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`key`),
  UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC))
ENGINE = InnoDB;

但是在阅读了InnoDB之后,我发现InnoDB使用聚簇索引组织数据,二级索引需要多次查找。一个用于二级索引,另一个用于主键(源)。因此,我正在讨论切换到以下内容:

#TABLE 4
CREATE TABLE `example` (
  `id` BIGINT(20) NOT NULL,
  `state` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`, `state`))
ENGINE = InnoDB;

想知道我所有的假设是否正确:

  1. MyISAM表锁定整个表以进行插入,更新和删除,一次只允许一个会话更新这些表
  2. InnoDB处理具有复合主键的插入比MyISAM更快。这是因为与MyISAM不同,InnoDB不会锁定整个表以扫描和保留新的主键。
  3. 使用 InnoDB 时,我应该创建一个复合主键而不是复合唯一索引,因为二级索引需要多次查找。
  4. 我应该使用表 4

1-是, 2-是, 3-是, 4-是.

也。。。

  • 你真的需要BIGINT吗? 40亿个价值INT UNSIGNED还不够吗? (并节省一半的空间。 大概其他表的PK id? 如果是这样,该表也需要更改。
  • state可以规范化吗? 还是变成了ENUM? 再次节省空间。

第 3 项比提到的更糟糕,因为需要锁定两个唯一键。

最新更新