我的简单MySql查询不使用索引

时间:2012-04-15 08:51:24

标签: mysql select indexing

我有一个非常简单的查询:

  SELECT   comments.*
  FROM comments 
  WHERE comments.imageid=46

这是我的表:

CREATE TABLE IF NOT EXISTS `comments` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `imageid` int(10) unsigned NOT NULL DEFAULT '0',
  `uid` bigint(20) unsigned NOT NULL DEFAULT '0',
  `content` text CHARACTER SET utf8,
  `adate` datetime DEFAULT NULL,
  `ip` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `ids` (`imageid`) USING BTREE,
  KEY `dt` (`adate`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;

但是MySql不能在这个简单的查询中使用索引。这是解释结果:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  comments    ALL     ids     NULL    NULL    NULL    4   75.00   Using where

当我将查询更改为此时,Mysql可以使用索引。为什么? :

  SELECT   comments.id
  FROM comments 
  WHERE comments.imageid=46

这里是解释:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  comments    ref     ids     ids     4   const   4   100.00  Using index

3 个答案:

答案 0 :(得分:7)

我猜你在'comments'表中有几行,这就是为什么MySQL在你的第一个查询中进行全表扫描而不是使用索引的原因。它估计全表扫描的成本可能低于第一次匹配索引,然后查找行。

在第二个查询中使用索引,因为可以直接从索引获取查询的所有列('id'列),而不需要在匹配索引后查找表行。这是“使用索引”额外信息的含义。

如果在'comments'中有大量行,请尝试MySQL仍使用完整扫描,我认为这将是一种奇怪的行为。事实上,我在MySQL版本5.1中测试的完全相同,即使只有很少的行,它总是使用'​​索引'。

答案 1 :(得分:1)

您是否尝试过the standard sort of things?

答案 2 :(得分:1)

第二个查询是索引覆盖的查询。可以从索引中读取所请求的全部信息(因为主键是InnoDB中任何二级索引的一部分)。

在第一个查询中,MySQL必须从索引中读取PK,然后读取行。因为表具有如此少量的行,所以优化器决定如果直接读取行并丢弃那些不匹配的行会更快