在同一列上有一个唯一且正常的索引有多错?

时间:2008-11-15 06:32:10

标签: mysql indexing unique-index

我有以下表结构

CREATE TABLE `table` (
  `id` int(11) NOT NULL auto_increment,
  `date_expired` datetime NOT NULL,
  `user_id` int(11) NOT NULL,
  `foreign_id` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `date_expired` (`date_expired`,`user_id`,`foreign_id`),
  KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

正如您将注意到的,我在user_id上有重复索引:date_expired& user_id。我当然想要唯一的索引,因为我想确保数据是唯一的。

重复索引的原因是因为没有user_id索引,我的主搜索查询需要4秒。使用额外的索引需要1秒钟。该查询正在加入user_id上的表并检查date_expired

该表只有275条记录。

  • 在同一个字段上拥有唯一且正常的索引有多糟糕?
  • 当表格纯粹为ids时,拥有比数据更大的索引有多糟糕?

3 个答案:

答案 0 :(得分:8)

我相信如果您创建了唯一索引(user_iddate_expiredforeign_id),那么在user_id上获得正常索引会获得相同的好处只有独特的索引。 MySQL可以使用任何索引的第一列来减少连接中的行数,其方式与user_id上的索引相同。

有关详细信息,请参阅MySQL's index documentation

您是指在架构中的其他地方使用id auto_increment列来节省空间吗?由于您的唯一索引涵盖了表中的所有其他列,因此它本质上是主键本身,如果不是,则可以删除。

您可以通过在EXPLAIN前面添加前缀来查看查询所使用的密钥。

答案 1 :(得分:3)

我不明白重复索引是什么意思。表中有三个索引:

  1. 一个用于主键'id'(暗示唯一)
  2. 另一个独特的'date_expired','user_id'和'foreign_id'组合
  3. 仅有'user_id'的第三个
  4. 所以没有重复,你有三个不同的索引,它们会做不同的事情。您需要3号来加速与user_id相关的查询,这是您所看到的。所以这个特定的表没有任何问题,你没有重复任何东西。关于第二个问题,它取决于你的需求,但肯定不是不好在索引中占用的空间比在数据中消耗的空间多。

    例如,有一个UNIQUE('user_id')和一个KEY('user_id')(我甚至不确定MySQL是否允许这样做)会有什么不好,因为一个索引会包含另一个索引并没有什么可以获得的。

答案 2 :(得分:1)

包含一个字段的多个索引根本不坏(实质上,它们会对不同的东西进行索引)。它对写入性能有轻微影响,但这是您首先对每个索引进行的典型权衡。 如果空间很便宜,索引占用的空间比数据本身还要多。在你的情况下,考虑到你的条目数量非常少,它应该很便宜。

我要问你的问题是:这样一个小表的索引如何严重影响我的查询运行时?也许你做错了什么(我想到这个表中有很多可能是多​​余的查询),因为单个条目应该远远没有这个时间范围,只有这么少的条目。)