简体   繁体   English

MyISAM与InnoDB的快速插入和复合唯一键

[英]MyISAM vs InnoDB for quick inserts and a composite unique key

Context: I'm creating a multi-threaded application that will be inserting/updating rows very frequently. 上下文:我正在创建一个多线程应用程序,该应用程序将非常频繁地插入/更新行。

Originally I had the following table: 最初我有下表:

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

However after doing some research I found that MySQL uses table-level locking for MyISAM tables permitting only one session to update those tables at a time ( source ). 但是,在进行了一些研究之后,我发现MySQL对MyISAM表使用表级锁定,仅允许一个会话一次更新这些表( )。 Not good for a multi-threaded application making frequent changes to the table. 对于频繁更改表的多线程应用程序不利。

As such, it was suggested that I switch from a composite primary key to an auto-generated primary key with a unique index for id/state. 因此,建议我从复合主键切换到具有唯一ID /状态索引的自动生成的主键。 This would allow for quick inserts while still enforcing the unique combination of the 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 however avoids table locks and instead uses row-level locking ( source ) so I thought of switching over to the following: 但是,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;

But after reading up about InnoDB, I discovered InnoDB organizes data using a clustered index and secondary indexes require multiple look ups. 但是,在阅读了有关InnoDB的内容之后,我发现InnoDB使用聚簇索引来组织数据,而二级索引则需要多次查找。 One for the secondary index and another for the primary key ( source ). 一个用于辅助索引,另一个用于主键( )。 As such I'm debating switching to the following: 因此,我想切换到以下内容:

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

I'm wondering if all my assumptions are correct: 我想知道我所有的假设是否正确:

  1. MyISAM table locks the entire table for INSERTS, UPDATES, and DELETES permitting only one session to update those tables at a time MyISAM表将整个表锁定为INSERTS,UPDATES和DELETES,一次仅允许一个会话更新这些表
  2. InnoDB handles INSERTS with composite primary keys quicker than MyISAM. InnoDB处理复合主键的INSERTS的速度比MyISAM快。 This is because InnoDB, unlike MyISAM, does not lock the entire table to scan and reserve a new primary key. 这是因为与MyISAM不同,InnoDB不会锁定整个表来扫描和保留新的主键。
  3. When using InnoDB I should make a composite primary key rather than a composite unique index because a secondary index requires multiple look ups. 使用InnoDB时,我应该创建一个复合主键而不是一个复合唯一索引,因为辅助索引需要多次查找。
  4. I should be using Table 4 我应该使用表4

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

Also... 也...

  • Do you really need BIGINT ? 您真的需要BIGINT吗? Won't 4 billion values in INT UNSIGNED suffice? INT UNSIGNED 40亿个值不够吗? (And save half the space.) Presumably id is the PK of some other table? (并节省一半的空间。)大概id是其他表的PK? If so, that table would need changing, too. 如果是这样,该表也需要更改。
  • Can state be normalized? state可以规范化吗? Or turned into an ENUM ? 还是变成了ENUM Again saving space. 再次节省空间。

Item 3 is worse than mentioned because of the need to lock on two unique keys. 由于需要锁定两个唯一的键,所以第3项比提到的要差。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM