我有以下表结构
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条记录。
答案 0 :(得分:8)
我相信如果您创建了唯一索引(user_id
,date_expired
,foreign_id
),那么在user_id
上获得正常索引会获得相同的好处只有独特的索引。 MySQL可以使用任何索引的第一列来减少连接中的行数,其方式与user_id
上的索引相同。
有关详细信息,请参阅MySQL's index documentation。
您是指在架构中的其他地方使用id
auto_increment列来节省空间吗?由于您的唯一索引涵盖了表中的所有其他列,因此它本质上是主键本身,如果不是,则可以删除。
您可以通过在EXPLAIN前面添加前缀来查看查询所使用的密钥。
答案 1 :(得分:3)
我不明白重复索引是什么意思。表中有三个索引:
所以没有重复,你有三个不同的索引,它们会做不同的事情。您需要3号来加速与user_id相关的查询,这是您所看到的。所以这个特定的表没有任何问题,你没有重复任何东西。关于第二个问题,它取决于你的需求,但肯定不是不好在索引中占用的空间比在数据中消耗的空间多。
例如,有一个UNIQUE('user_id')和一个KEY('user_id')(我甚至不确定MySQL是否允许这样做)会有什么不好,因为一个索引会包含另一个索引并没有什么可以获得的。
答案 2 :(得分:1)
包含一个字段的多个索引根本不坏(实质上,它们会对不同的东西进行索引)。它对写入性能有轻微影响,但这是您首先对每个索引进行的典型权衡。 如果空间很便宜,索引占用的空间比数据本身还要多。在你的情况下,考虑到你的条目数量非常少,它应该很便宜。
我要问你的问题是:这样一个小表的索引如何严重影响我的查询运行时?也许你做错了什么(我想到这个表中有很多可能是多余的查询),因为单个条目应该远远没有这个时间范围,只有这么少的条目。)