我有以下mysql查询
select points_for_user from items where user_id = '38415';
解释查询返回此
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE items index NULL points_for_user_index 2 NULL 1000511 Using index
问题是,由于索引,行数是否应该小于表中的行数?
user_id是主索引,因此我尝试仅在points_for_user上创建索引,并且仍然查看每一行。 user_id上的索引AND points_for_user仍会搜索每一行。
我错过了什么?
谢谢!
CREATE TABLE IF NOT EXISTS `items` (
`capture_id` int(11) NOT NULL AUTO_INCREMENT,
`id` int(11) NOT NULL,
`creator_user_id` bigint(20) NOT NULL DEFAULT '0',
`user_id` int(11) NOT NULL,
`accuracy` int(11) NOT NULL,
`captured_at` timestamp NOT NULL DEFAULT '2011-01-01 06:00:00',
`ip` varchar(30) NOT NULL,
`capture_type_id` smallint(6) NOT NULL DEFAULT '0',
`points` smallint(6) NOT NULL DEFAULT '5',
`points_for_user` smallint(6) NOT NULL DEFAULT '3',
PRIMARY KEY (`capture_id`),
KEY `capture_user` (`capture_id`,`id`,`user_id`),
KEY `user_id` (`user_id`,`id`),
KEY `id` (`id`),
KEY `capture_creator_index` (`capture_id`,`creator_user_id`),
KEY `points_capture_index` (`points_for_user`,`creator_user_id`),
KEY `points_for_user_index` (`points_for_user`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1008992 ;
select count(*) from items where user_id = '38415'
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE captures ref user_munzee_id user_munzee_id 4 const 81 Using index
答案 0 :(得分:0)
mysql优化器尝试在查询期间使用最佳索引。
在你的第一个查询中,优化器正在考虑将points_for_user_index作为最佳选择,实际上Extra列显示“Using index”状态,这意味着“覆盖索引”。
当查询所需的所有字段(在您的情况下从...中选择points_for_user)包含在索引中时,会出现“覆盖索引”,这样就可以避免访问完整的mysql数据(.MYD)而有利于直接索引访问(.MYI)
首先,您可以尝试重建索引树分析表
ANALYZE TABLE itemes;
请注意非常大的表格:
ANALYZE TABLE分析并存储表的密钥分发。 在分析过程中,表被锁定,InnoDB具有读锁定功能 和MyISAM。此语句适用于InnoDB,NDB和MyISAM表。 对于MyISAM表,此语句等同于使用myisamchk --analyze。
如果“问题”仍然存在且你想绕过优化器选择,你可以明确地尝试强制使用索引
EXPLAIN SELECT points_for_user FROM items USE INDEX ( user_id ) WHERE user_id = '38415'
更多详情:http://dev.mysql.com/doc/refman/5.5/en/index-hints.html
的Cristian