UNIQUE约束是否自动在字段上创建索引?


97

我应该在列上定义一个单独的索引email(出于搜索目的),还是该索引是“自动”与UNIQ_EMAIL_USER约束一起添加的?

CREATE TABLE IF NOT EXISTS `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `first` varchar(255) NOT NULL,
  `last` varchar(255) NOT NULL,
  `slug` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_SLUG` (`slug`),
  UNIQUE KEY `UNIQ_EMAIL_USER` (`email`,`user_id`),
  KEY `IDX_USER` (`user_id`)
) ENGINE=InnoDB;

编辑:根据科宾的建议,我EXPLAIN SELECT * FROM customer WHERE email = 'address'在空桌上查询。这是结果,我不知道如何解释:

id select_type type possible_keys key  key_len ref  rows Extra
1  SIMPLE      ALL  NULL          NULL NULL    NULL 1    Using where

将IXD_EMAIL添加到表中时,相同的查询显示:

id select_type type possible_keys key       key_len ref   rows Extra
1  SIMPLE      ref  IDX_EMAIL     IDX_EMAIL 257     const 1    Using where

1
从技术上讲,UNIQUE约束不需要索引...但是不确定标准如何定义它或MySQL(哪个后端,btw?)实现它。我很快可以在MySQL中手动找到的所有内容是:“唯一索引创建了一个约束,因此索引中的所有值都必须是唯一的”。

您需要使用单独的vs覆盖(AKA组合-多于一列)索引来实施和测试。这取决于用途和数据。
OMG Ponies 2012年

3
我99%确信确实可以创建索引。只需创建一个具有唯一性的表,然后对带有where的select进行解释。
科宾(Corbin)2012年

@Corbin做到了,我应该如何解释结果?
gremo

它是否使用唯一约束作为索引?顺便说一下,您可能需要使用非常大的表,或者可能只是进行表扫描。
科宾(Corbin)2012年

Answers:


115

一个独特的关键是指数的一个特例,像个与独特性增加检查的常规指标。使用SHOW INDEXES FROM customer您可以看到您的唯一键实际上是B树类型索引。

一个综合指数(email, user_id)是不够的,你不需要只电子邮件单独的索引- MySQL能使用复合指数的最左边的部分。在某些边界情况下,索引的大小可能会使查询变慢,但是在真正遇到它们之前,您不必担心它们。

至于测试索引的使用,您应该首先在表中填充一些数据,以使优化程序认为使用该索引确实值得。


EXPLAIN由于空表,所以测试显示虚假值?
gremo

我不确定您如何设法获得解释结果,我只是复制了表定义,并且相同的解释显示UNIQ_EMAIL_USER为可能的键,请您重新检查一下?
piotrm 2012年

好的,找到了窍门。如果user_id先使用定义了约束,则email不会在中显示约束EXPLAIN。你知道吗?
gremo

10
它不起作用,因为电子邮件不是(user_id,email)对的最左部分。您不能沿着b树仅使用最右边的部分来查找行。
piotrm 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.