7

我有以下表结构

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 条记录。

  • 在同一字段上拥有唯一且正常的索引有多糟糕?
  • 当表是纯 id 时,索引比数据大有多糟糕?
4

3 回答 3

9

我相信,如果您将唯一索引创建为 ( user_id, date_expired, ),那么您将获得与仅使用唯一索引foreign_id建立正常索引相同的好处。user_idMySQL 可以使用任何索引的第一列来减少连接中的行数,其方式与user_id.

有关更多信息,请参阅MySQL 的索引文档

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

您可以通过在查询前加上 EXPLAIN 来检查查询使用的键。

于 2008-11-15T06:50:06.297 回答
3

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

  1. 一个用于主键“id”(这意味着唯一)
  2. 'date_expired'、'user_id' 和 'foreign_id' 组合的另一个独特的
  3. 第三个仅超过 'user_id'

所以没有重复,你有三个不同的索引可以做不同的事情。您需要 3 号来加快与您所看到的 user_id 相关的查询。所以这个特定的表没有任何问题,你没有复制任何东西。关于第二个问题,这取决于您的需求,但是在索引中使用的空间比在数据中使用的空间多当然也不错。

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

于 2008-11-15T06:39:18.923 回答
1

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

我会问你的问题是:这么小的表的索引如何严重影响我的查询运行时间?也许你做错了什么(我认为这个表有很多可能冗余的查询),因为只有这么少的条目,单个查询应该不会接近这个时间范围)。

于 2008-11-15T06:37:54.903 回答