在解释MySQL查询期间使用Where

时间:2017-02-12 10:27:37

标签: mysql

我在查询时有一张表,

EXPLAIN SELECT `id`
FROM `tblsender`
WHERE `userid` = '6'
AND `astatus` = '1'
AND `sender` = 'ABCDEF'

即使在以所有可能的方式编制索引之后,我仍然获得USING WHERE。这是我的最终表结构代码。

CREATE TABLE IF NOT EXISTS `tblsender` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sender` varchar(6) NOT NULL,
`astatus` tinyint(1) NOT NULL DEFAULT '0',
`userid` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `astatus` (`astatus`),
KEY `userid` (`userid`),
KEY `sender` (`sender`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=22975 ;

我甚至尝试了sender列的全文,但仍然没有运气,我也尝试对所有where clause列进行索引。

ALTER TABLE `tblsender` ADD INDEX ( `sender` , `astatus` , `userid` ) ;

仍然获得using where,我该如何正确索引此表。

编辑:解释上述结构的输出。

id  select_type table       type    possible_keys           key     key_len     ref     rows    Extra   
1   SIMPLE      tblsender   ref     astatus,userid,sender   astatus     1       const   1       Using where

并解释所有3列的输出

id  select_type table       type    possible_keys                   key     key_len     ref     rows    Extra
1   SIMPLE      tblsender   ref     astatus,userid,sender,sender_2  astatus     1       const   1       Using where

1 个答案:

答案 0 :(得分:4)

使用小型数据集进行测试时,无法有效预测大型数据集上的优化器行为。

如查询计划所示,多列索引被视为候选者,但优化器选择不使用(在本例中为)。这并不意味着当它被认为更有益时它不会使用它。

我只能在没有看到您的实际数据集并且可能使用optimizer tracing的情况下进行推测,但我会提供合理的推测。

MySQL中的优化器是基于成本的。它尝试以最便宜的方式解决您的查询。请注意rows = 1.这意味着优化器已经得出结论 - 从统计上来说,至少 - 它期望在astatus的索引中只有1行匹配。 key_len = 1,意味着astatus只有1个字节宽 - 与多列索引相反,即11个字节宽(1 + 6 + 4) - astatus index看起来是一个非常便宜的解决方案,所以它决定使用该索引。理论上使用较长的索引意味着更多的I / O,因此成本更高,尽管在这种情况下(由于数据集很小),我们人类认识到成本差异并不是特别有意义。

Using where表示对于使用该索引实际返回的每一行,服务器需要验证行是否与WHERE子句的其余部分匹配,但是如果我们只期望大约1要匹配,这没什么大不了的。

我建议您没有理由担心,因为当前数据集的小尺寸无法为您提供预测未来行为的有用信息。在这种特定情况下,Using where是表中少量行的工件。

您需要更多数据。但是,是的,你确实需要一个多列索引。