我查看了多篇类似的帖子,试图获取有关如何重新定义索引的输入,但无法弄清楚这一点。每次我包含ORDER BY语句时,它都使用filesort返回结果集。
这是表定义和查询:
SELECT
`s`.`title`,
`s`.`price`,
`s`.`price_sale`
FROM `style` `s`
WHERE `s`.`isactive`=1 AND `s`.`department`='women'
ORDER
BY `s`.`ctime` DESC
CREATE TABLE IF NOT EXISTS `style` (
`id` mediumint(6) unsigned NOT NULL auto_increment,
`ctime` timestamp NOT NULL default CURRENT_TIMESTAMP,
`department` char(5) NOT NULL,
`isactive` tinyint(1) unsigned NOT NULL,
`price` float(8,2) unsigned NOT NULL,
`price_sale` float(8,2) unsigned NOT NULL,
`title` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_grid_default` (`isactive`,`department`,`ctime`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=47 ;
另外,这是我得到的解释结果集:
+----+-------------+-------+------+---------------+----------+---------+-------------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------+---------+-------------+------+-----------------------------+
| 1 | SIMPLE | s | ref | idx_grid | idx_grid | 6 | const,const | 3 | Using where; Using filesort |
+----+-------------+-------+------+---------------+----------+---------+-------------+------+-----------------------------+
答案 0 :(得分:3)
为什么s.isactive
不能用作索引?
MySQL(或任何相关的SQL)如果基数较低,则不会使用密钥。 用简单的英语,如果许多行共享一个键的相同值,(My)SQL将不使用索引,而只是实际的表。
因此,布尔字段几乎从未被选为索引;太多行共享相同的值。
为什么MySQL不在ctime上使用索引?
ctime
包含在多字段或composite
索引中。 MySQL将只使用复合索引如果你使用它的全部或最左边的部分 *)
如果对复合索引的中间或最右边的字段进行排序,MySQL就无法使用索引,并且必须求助于filesort。
因此order by isactive , department
将使用索引;
order by department
不会
order by isactive
也不会使用索引,但这是因为布尔字段isactive
的基数太低。
*)有一些例外,但这涵盖了97%的案例。
<强>链接:强>
基数维基百科:http://en.wikipedia.org/wiki/Cardinality_%28data_modeling%29
http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
答案 1 :(得分:1)
What does Using filesort mean in MySQL?
这并不意味着你有一个临时文件,它只是意味着排序已经完成(错误的名称,忽略4个首字母)。
来自 Baron Schwartz :
事实是,filesort的名字很糟糕。无论何时无法从索引执行排序,它都是一个文件排序。它与文件无关。应该将Filesort称为“排序”。它很快就会出类拔萃。