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

时间:2016-07-07 22:04:54

标签: mysql innodb myisam composite-primary-key

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

最初我有下表:

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

然而,经过一些研究后,我发现MySQL对MyISAM表使用表级锁定,只允许一个会话一次更新这些表(source)。对于经常更改表的多线程应用程序不利。

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

#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避免了表锁,而是使用行级锁定(source),所以我想切换到以下内容:

#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使用聚簇索引来组织数据,而二级索引需要多次查找。一个用于辅助索引,另一个用于主键(source)。因此,我正在讨论切换到以下内容:

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

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

  1. MyISAM表锁定整个表的INSERTS,UPDATES和DELETES,一次只允许一个会话更新这些表
  2. InnoDB使用复合主键处理INSERTS比MyISAM更快。这是因为与MyISAM不同,InnoDB不会锁定整个表以扫描和保留新的主键。
  3. 使用InnoDB时,我应该制作复合主键而不是复合唯一索引,因为辅助索引需要多次查找。
  4. 我应该使用表4

1 个答案:

答案 0 :(得分:3)

1-yes,2-yes,3-yes,4-yes。

也...

  • 你真的需要BIGINT吗? INT UNSIGNED中不会有40亿个值吗? (并节省一半的空间。)据推测id是其他桌子的PK?如果是这样,那个表也需要改变。
  • state可以正常化吗?或者变成ENUM?再次节省空间。

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