我们有一个由三个字段的复合主键的表(它是在MySQL 5.1)。 有近200个插入和每秒200个选择在此表,并且该表的大小为大约1百万行和它正在增加。
我的问题是:在“复合主键”降低插入,并选择在此表上的表现?
我应该使用一个简单的自动增加INT ID字段,而不是一个复合主键? (我认为答案是有很大关系的MySQL处理上多列索引的方式)
我们有一个由三个字段的复合主键的表(它是在MySQL 5.1)。 有近200个插入和每秒200个选择在此表,并且该表的大小为大约1百万行和它正在增加。
我的问题是:在“复合主键”降低插入,并选择在此表上的表现?
我应该使用一个简单的自动增加INT ID字段,而不是一个复合主键? (我认为答案是有很大关系的MySQL处理上多列索引的方式)
INSERT
和UPDATE
性能几乎没有变化:这将是几乎相同(INT)
和(INT, INT)
键。
SELECT
复合材料的性能PRIMARY KEY
取决于很多因素。
如果您的表是InnoDB
,那么该表隐聚集在PRIMARY KEY
值。
这意味着,这两个值的搜索会更快,如果这两个值包括关键:没有多余的键查找是必需的。
假设你的查询是这样的:
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
,发动机将只需要在查找表本身的确切键值。
如果使用自动增量字段作为假身份证:
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
,那么发动机就需要,首先,查找值(col1, col2)
在指数ix_mytable_col1_col2
,检索索引的值(行指针id
)再拍查询通过id
在表本身。
对于MyISAM
表,但是,这并没有区别,因为MyISAM
表是堆组织和行指针只是文件偏移。
在两种情况下,一个相同的索引将被创建(为PRIMARY KEY
或UNIQUE KEY
),将在同样的方式使用。
如果它是InnoDB的,复合主密钥将被包括在每一个二级索引的每个条目。
这意味着
这些分别是当然,缺点和优点的。
复合主键并不一定是坏事,有时也可以是真正有用的,因为InnoDB的聚类他们 - 这意味着(光盘绑定)范围扫描过的PK可以用少得多的IO操作比在非聚集索引将需要得到满足。
当然,如果你已经在其他表有外键,它们是更广泛的,以及他们需要包括从你的主餐桌的全键。
但我要说的平衡,一般没有。 有一个复合主键本身并不造成问题。 有一个“大”主键(如大VARCHAR处理),但是可以做,如果远远超过集群的优势,并能够使用覆盖索引。
SELECT
SA点点,虽然效果是非常微不足道的,不值得担心。 INSERT
S,你肯定是做足够的INSERT
s到担心。 这是更多,如果它是一个MyISAM表关注,其中一个的INSERT
锁定表,比如果它是一个InnoDB表。 如果,通过与AUTO_INCREMENT主键去,你就可以离开这些列未索引,你将受益于变化。 如果你仍然需要保持这些三列索引,但(例如,如果您需要强制执行他们的组合独特性),它是不会为你做任何事的性能代价。