MyISAM vs InnoDB 用于快速插入和复合唯一键
MyISAM vs InnoDB for quick inserts and a composite unique key
上下文:我正在创建一个多线程应用程序,该应用程序将非常频繁地 inserting/updating 行。
最初我有以下 table:
#TABLE 1
CREATE TABLE `example` (
`id` BIGINT(20) NOT NULL,
`state` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`, `state`))
ENGINE = MyISAM;
然而,在做了一些研究之后,我发现 MySQL 使用 table 级锁定 MyISAM tables 只允许一个会话更新那些 tables时间(source)。不适合频繁更改 table.
的多线程应用程序
因此,有人建议我从复合主键切换到具有 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 但是避免了 table 锁,而是使用行级锁定(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;
我想知道我的所有假设是否正确:
- MyISAM table 为插入、更新和删除锁定整个 table,只允许一个会话一次更新这些 table
- InnoDB 比 MyISAM 更快地处理带有复合主键的 INSERTS。这是因为 InnoDB 与 MyISAM 不同,不会锁定整个 table 以扫描并保留新的主键。
- 当使用 InnoDB 时,我应该创建复合主键而不是复合唯一索引,因为二级索引需要多次查找。
- 我应该使用 Table 4
1-是,2-是,3-是,4-是。
还有...
- 你真的需要
BIGINT
吗? INT UNSIGNED
中的 40 亿个值是否足够? (还省了一半space。) 想必id
是其他table的PK吧?如果是这样,那 table 也需要改变。
state
可以归一化吗?还是变成了ENUM
?再次保存 space.
项目 3 比提到的更糟糕,因为需要锁定两个唯一键。
上下文:我正在创建一个多线程应用程序,该应用程序将非常频繁地 inserting/updating 行。
最初我有以下 table:
#TABLE 1
CREATE TABLE `example` (
`id` BIGINT(20) NOT NULL,
`state` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`, `state`))
ENGINE = MyISAM;
然而,在做了一些研究之后,我发现 MySQL 使用 table 级锁定 MyISAM tables 只允许一个会话更新那些 tables时间(source)。不适合频繁更改 table.
的多线程应用程序因此,有人建议我从复合主键切换到具有 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 但是避免了 table 锁,而是使用行级锁定(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;
我想知道我的所有假设是否正确:
- MyISAM table 为插入、更新和删除锁定整个 table,只允许一个会话一次更新这些 table
- InnoDB 比 MyISAM 更快地处理带有复合主键的 INSERTS。这是因为 InnoDB 与 MyISAM 不同,不会锁定整个 table 以扫描并保留新的主键。
- 当使用 InnoDB 时,我应该创建复合主键而不是复合唯一索引,因为二级索引需要多次查找。
- 我应该使用 Table 4
1-是,2-是,3-是,4-是。
还有...
- 你真的需要
BIGINT
吗?INT UNSIGNED
中的 40 亿个值是否足够? (还省了一半space。) 想必id
是其他table的PK吧?如果是这样,那 table 也需要改变。 state
可以归一化吗?还是变成了ENUM
?再次保存 space.
项目 3 比提到的更糟糕,因为需要锁定两个唯一键。