MySQL 5.0 索引 - 唯一与非唯一

Posted

技术标签:

【中文标题】MySQL 5.0 索引 - 唯一与非唯一【英文标题】:MySQL 5.0 indexes - Unique vs Non Unique 【发布时间】:2010-09-28 04:30:16 【问题描述】:

mysql 唯一索引和非唯一索引在性能方面有什么区别?

假设我想在 2 列的组合上创建一个索引,并且该组合是唯一的,但我创建了一个非唯一索引。这会对 MySQL 使用的性能或内存产生重大影响吗?

同样的问题,primary key和unique index有区别吗?

【问题讨论】:

【参考方案1】:

UNIQUE 和 PRIMARY KEY 是约束,而不是索引。尽管大多数数据库通过使用索引来实现这些约束。除了索引之外,约束的额外开销是微不足道的,尤其是当您计算跟踪和纠正意外重复(而不是如果)发生时的成本时。

如果您有较高的选择性,索引通常会更有效。这是不同值的数量与总行数的比率。

例如,在社会安全号码列中,您可能有 100 万行具有 100 万个不同的值。所以选择性是 1000000/1000000 = 1.0(虽然历史上很少有例外,但 SSN 的目的是唯一的)。

但该表中的另一列“性别”可能只有两个不同的值,超过 100 万行。 2/1000000 = 选择性非常低。

具有 UNIQUE 或 PRIMARY KEY 约束的索引保证具有 1.0 的选择性,因此它将始终与索引一样有效。

您询问了主键和唯一约束之间的区别。主要是每个表只能有一个主键约束(即使该约束的定义包括多个列),而您可以有多个唯一约束。具有唯一约束的列可能允许 NULL,而主键约束中的列不得允许 NULL。否则,主键和唯一键的实现和使用非常相似。

您在评论中询问是否使用 MyISAM 或 InnoDB。在 MySQL 中,他们使用术语存储引擎。这两种存储引擎之间存在许多细微差别,但主要有:

InnoDB 支持事务,因此您可以选择回滚或提交更改。 MyISAM 实际上总是自动提交。 InnoDB 强制执行外键约束。 MyISAM 不强制甚至不存储外键约束。

如果您的应用程序需要这些功能,那么您应该使用 InnoDB。


要回复您的评论,没那么简单。在很多情况下,InnoDB 实际上比 MyISAM 更快,因此这取决于您的应用程序的选择、更新、并发查询、索引、缓冲区配置等的组合。

请参阅http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/ 以获得对存储引擎的非常全面的性能比较。 InnoDB 频繁地战胜 MyISAM,显然不可能说其中一个比另一个快。

与大多数与性能相关的问题一样,为您的应用程序回答问题的唯一方法是使用您的应用程序和具有代表性的数据样本测试这两种配置,然后测量结果。

【讨论】:

"将永远是..." 只要您的查询为索引中的每个字段提供了一个值;并且提供的值都不为空;并且键中的所有字段都不能为空(排序)。 所以这实际上意味着如果我不需要事务/外键约束,最好使用 MyISAM,我们可以期待它有更好的性能。 哈哈,在我向下滚动到第一段之前,我总是知道什么时候会是 Bill Karwin 的回答 :) 总是清晰而有见地,谢谢 +1【参考方案2】:

在恰好是唯一的非唯一索引和唯一索引上?我不确定,但我猜不会很多。优化器应检查索引的基数并使用它(对于唯一索引,它始终是行数)。

就主键而言,可能很多,但这取决于您使用的引擎。

InnoDB 引擎(被很多人使用)总是将行聚集在主键上。这意味着 PK 本质上是与实际行数据相结合的。如果您通过 PK(或者实际上,范围扫描等)进行大量查找,这是一件好事,因为这意味着它不需要从磁盘中获取尽可能多的块。

非 PK 唯一索引永远不会在 InnoDB 中聚集。

另一方面,其他一些引擎(尤其是 MyISAM)不会对 PK 进行聚类,因此主键就像一个普通的唯一索引。

【讨论】:

这将我带到第二个问题,使用哪个索引 - 我个人更喜欢 MyISAM,因为听说它具有更好的选择查询性能,并且在我恢复 mysqldump 时速度更快。为什么我应该使用 InnoDB?

以上是关于MySQL 5.0 索引 - 唯一与非唯一的主要内容,如果未能解决你的问题,请参考以下文章

(2.8)Mysql之SQL基础——索引的分类与使用

MySQL的并发控制与加锁分析

如何使用Spring Data JPA搜索非唯一索引?

MySQL中一条SQL的加锁分析

MYSQL锁机制 - 锁的简述 | 索引对行级锁的影响

MYSQL锁机制 - 锁的简述 | 索引对行级锁的影响