MySQL中复合主键性能的缺点

我们有一个包含三个字段的组合主键(在MySQL 5.1中)。 在这个表上每秒钟有200个插入和200个select,并且表的大小约为100万行,并且正在增加。

我的问题是:“复合主键”是否会降低此表上插入和select的性能?

我应该使用简单的自动增加INT ID字段而不是复合主键吗? (我想这个答案和MySQL在多列上处理索引的方式非常相关)

INSERTUPDATE性能差别不大: (INT)(INT, INT)键几乎相同。

复合PRIMARY KEY SELECT性能取决于许多因素。

如果你的表是InnoDB ,那么这个表隐式地聚集在PRIMARY KEY值上。

这意味着,如果两个值都包含关键字,则对两个值的search将会更快:不需要额外的密钥查找。

假设你的查询是这样的:

 SELECT * FROM mytable WHERE col1 = @value1 AND col2 = @value2 

和表格布局是这样的:

 CREATE TABLE mytable ( col1 INT NOT NULL, col2 INT NOT NULL, data VARCHAR(200) NOT NULL, PRIMARY KEY pk_mytable (col1, col2) ) ENGINE=InnoDB 

,引擎只需要在表格中查找确切的键值。

如果您使用自动增量字段作为伪造ID:

 CREATE TABLE mytable ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, col1 INT NOT NULL, col2 INT NOT NULL, data VARCHAR(200) NOT NULL, UNIQUE KEY ix_mytable_col1_col2 (col1, col2) ) ENGINE=InnoDB 

那么引擎将首先需要查找索引ix_mytable_col1_col2(col1, col2)的值,从索引( id的值(col1, col2)中检索行指针,并在表中通过id进行另一个查找。

但是,对于MyISAM表而言,这没什么区别,因为MyISAM表是堆组织的,行指针只是文件偏移量。

在这两种情况下,都会创build一个相同的索引(对于PRIMARY KEYUNIQUE KEY ),并以相同的方式使用。

如果是InnoDB,则复合主键将包含在每个二级索引中的每个条目中。

这意味着

  • 您的二级索引将占用与这些列+主键中的所有列一样多的空间
  • 如果所有需要的列都包含在辅助索引+ pk中,则可以使用辅助索引作为覆盖索引

这些当然分别是缺点和优点。

复合主键不一定是坏的,有时它们可​​以真正有帮助,因为InnoDB将它们聚集在一起 – 这意味着使用less得多的IO操作就可以满足对PK的(磁盘绑定)范围扫描,这比非聚集索引。

当然,如果你在其他表中有外键,它们也会更宽,并且需要包含主表中的整个键。

但是总的来说,我会说平衡,不。 有一个复合主键本身不会引起问题。 然而,如果拥有“大”主键(例如大variables),则可能会超过聚类的优势,并且能够使用覆盖索引。

  1. 有了这个复合主键减慢SELECT一点点,虽然效果几乎可以忽略不计,不值得担心。
  2. 把这些列索引放慢你的INSERT ,你肯定做了足够的INSERT s来担心它。 如果它是一个MyISAM表, INSERTlocking表,比InnoDB表更重要。 如果通过使用auto_increment主键,您可以将这些列保持未索引,您将从中受益。 如果你仍然需要保留这三列的索引,但是(例如,如果你需要在它们的组合上强制执行唯一性),那么对于你来说在性能方面是不会做任何事情的。