在主键上使用唯一索引有什么性能差异吗?

Ism*_*uel 5 mysql myisam performance primary-key

我知道有很多与此类似的问题,但没有一个能真正回答这个问题:

在主键中使用唯一索引,在运行 MySQL 5.5 的服务器上使用 MyISAM 表,性能是否有任何差异?

如果您需要更多信息,我可以提供所有信息。
我只是想知道是否值得(可以说,如果“搜索”时间减少超过 5 毫秒)进行更改,或者我是否正在犯下可怕的罪行。

是的,这是一个严肃的问题。

jyn*_*nus 7

A PRIMARY KEYis, 根据定义, UNIQUEand NOT NULL,因此通过UNIQUE在其上添加第二个关键字,您实际上是在创建一个单独的索引。这不仅会降低效率,而且在某些情况下,还会降低查询的性能。

您可以通过执行以下操作来检查是否创建了两个索引:

mysql> SHOW CREATE TABLE test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(11) NOT NULL,
  `c` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

在 MyISAM 和 InnoDB 中,它都需要额外的空间,它会使写入变慢(因为索引必须在写入时同步更新),并且可能会浪费优化器(即使微秒)时间来决定哪个索引是最好的. MySQL 通常会在 MyISAM 中选择 PRIMARY 键,但是如果出于任何原因使用了两个索引,您也会浪费内存。

如果你不相信我,相信 MySQL:

mysql> INSERT test1 SELECT * from test;
Query OK, 1691648 rows affected (6.84 sec)
Records: 1691648  Duplicates: 0  Warnings: 0

mysql> create table test2 like test1;
Query OK, 0 rows affected (0.04 sec)

mysql> ALTER TABLE test2 add unique(id);
Query OK, 0 rows affected, 1 warning (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 1

mysql> INSERT test2 SELECT * from test;
Query OK, 1691648 rows affected (10.94 sec)
Records: 1691648  Duplicates: 0  Warnings: 0
Run Code Online (Sandbox Code Playgroud)

运行pt-duplicate-key-checker通常足以检测这些重复项。

如果您的意思是使用UNIQUE NOT NULL 而不是 PRIMARY KEY,我不希望在大多数情况下 MyISAM 有区别(尽管某些工具与 PK 配合使用效果更好,例如基于行的复制);InnoDB 不是这种情况,其中 PK 是其结构的基础(围绕它的集群行)。