Mysql如何创建聚簇索引?

时间:2012-12-08 15:59:28

标签: mysql sql clustered-index

我正在阅读关于聚簇索引如何工作的所有内容,并认为它们对我的应用程序有益。我知道主键是自动聚簇索引,但是如何将聚簇索引添加到非主键列?

即。用户帖子的数据存储区。每个帖子都有一个ID,但也有一个用户ID,但由于用户可以多次发帖,因此user-id不是主键。如何将聚集索引添加到用户ID,这甚至是个好主意?

4 个答案:

答案 0 :(得分:16)

根据Clustered and Secondary Indexes,每个表只能有一个聚簇索引。

  

聚簇索引以外的所有索引都称为辅助索引。

如果表没有主索引而是另一个唯一索引,则将其用作聚簇索引。

  

如果没有为表定义PRIMARY KEY,MySQL会找到第一个UNIQUE索引,其中所有键列都是NOT NULL,而InnoDB将它用作聚簇索引。

因此,我得出结论,您不会自己添加聚簇索引,但MySQL会选择表的主要或第一个唯一索引作为聚簇索引。

答案 1 :(得分:8)

正如@Olaf描述的那样,InnoDB选择哪个列或列组合将成为聚簇索引(主键,如果没有主键,则为第一个唯一索引;如果两个都没有,则选择隐藏列) 。

如果您希望将非唯一列作为聚簇索引,则可以将post_id定义为唯一键,并将user_idpost_id组合为主键将被选为聚集索引:

CREATE TABLE Post
( post_id INT NOT NULL AUTO_INCREMENT
, user_id INT NOT NULL
--- other columns
, CONSTRAINT Post_PK
    PRIMARY KEY (user_id, post_id)     -- your clustered index
, CONSTRAINT post_id_UQ
    UNIQUE (post_id)             -- you still want uniqueness for the `post_id`
) ENGINE = InnoDB ;

这是否是一个好主意取决于您的应用程序,数据量和您拥有的查询。通常,群集密钥的最佳属性是唯一的,窄的,静态的和不断增加的。这就是为什么自动递增列最好的原因。在Kimberly L. Tripp的博客文章中了解它:Ever-increasing clustering key - the Clustered Index Debate..........again!The Clustered Index Debate Continues...(不要停止,因为它们适用于SQL-Server,同样的问题适用于InnoDB的聚集索引99%)

(user_id, post_id)这样的聚类键具有前3个属性,但它不会增加。这将导致CI碎片化,并可能更慢地插入表中。

然而,它会产生更有效的查询,这些查询具有WHERE user_id = ?条件或范围条件WHERE user_id BETWEEN ? AND ?GROUP BY user_id分组,因为所需数据将在聚集索引中的某个位置找到所需的订单。

我建议您进行测试,以选择最适合您的情况。


还有一个MySQL变体TokuDB,允许在表中使用多个聚簇索引。文章中的详细信息: Introducing Multiple Clustering Indexes

答案 2 :(得分:1)

我建议你提出错误的问题。

另一个问题是"我可以摆脱目前的PRIMARY KEY,这样我就能做出另一件事了#39;群集'?"通常AUTO_INCREMENT可以被删除或变成简单的INDEX

更可能的问题是"这个SELECT ...的最佳索引是什么?"。其他人指出,对于基本的MySQL,第二个聚簇索引是不可能的,那么下一个选择是什么?在不知道SELECT的情况下,我无法回答这个问题。但是,my Index Cookbook回答了大量SELECTs的问题。

答案 3 :(得分:0)

当您为InnoDB表定义主键时,MySQL使用主键作为聚簇索引。

如果您没有表的主键,则MySQL将搜索第一个 UNIQUE索引,其中所有键列都不为空,并将此UNIQUE索引用作聚集索引。

>

如果InnoDB表没有主键或合适的UNIQUE索引,MySQL会在包含行ID值的综合列上内部生成一个名为 GEN_CLUST_INDEX 的隐藏的聚集索引。