mysql单表SELECT查询ORDER BY导致FILESORT
我浏览了多个类似的帖子,试图获取有关如何重新定义索引的信息,但无法弄清楚这一点。每次我包含 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 |
+----+-------------+-------+------+---------------+----------+---------+-------------+------+-----------------------------+
I looked through multiple similar posts trying to get input on how to redefine my index but can't figure this out. Every time i include the ORDER BY statement, it uses filesort to return the resultset.
Here's the table definition and query:
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 ;
Also, here's the explain result set I get:
+----+-------------+-------+------+---------------+----------+---------+-------------+------+-----------------------------+
| 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 |
+----+-------------+-------+------+---------------+----------+---------+-------------+------+-----------------------------+
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么
s.isactive
不被用作索引?如果键的基数较低,MySQL(或任何与此相关的SQL)将不会使用它。
简单来说,如果许多行共享相同的键值,(My)SQL 将不会使用索引,而只是使用真实的表。
因此,布尔字段几乎永远不会被选为索引;太多行共享相同的值。
为什么MySQL不使用ctime上的索引?
ctime
包含在多字段或复合
索引中。 MySQL 只会使用复合索引如果您使用它的全部或最左边的部分*)如果对复合索引的中间或最右边的字段进行排序,MySQL 将无法使用该索引,而必须求助于文件排序。
因此,
按 isactive 、部门进行的订单
将使用索引;按部门排序
不会。order by isactive
将也不会使用索引,但这是因为布尔字段isactive
的基数太低。*) 有一些例外,但这涵盖了 97% 的情况。
链接:
基数维基百科:http://en.wikipedia.org/wiki/Cardinality_%28data_modeling%29< /a>
http://dev.mysql.com/doc/refman/5.0 /en/mysql-indexes.html
Why does
s.isactive
not get used as an index?MySQL (or any SQL for that matter) will not use a key if it has low cardinality.
In plain English, if many rows share the same value for a key, (My)SQL will not use the index, but just real the table instead.
A boolean field almost never gets picked as an index because of this; too many rows share the same value.
Why does MySQL not use the index on ctime?
ctime
is included in a multi-field orcomposite
index. MySQL will only use a composite index if you use all of it or a left-most part of it *)If you sort on the middle or rightmost field(s) of a composite index, MySQL cannot use the index and will have to resort to filesort.
So a
order by isactive , department
will use an index;order by department
will not.order by isactive
will also not use an index, but that's because the cardinality of the boolean fieldisactive
is too low.*) there are some exceptions, but this covers 97% of cases.
Links:
Cardinality wikipedia: http://en.wikipedia.org/wiki/Cardinality_%28data_modeling%29
http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
在 MySQL 中使用 filesort 意味着什么?
这并不意味着你有一个临时文件,它只是意味着排序已经完成(坏名字,忽略前 4 个字母)。
来自施瓦茨男爵:
What does Using filesort mean in MySQL?
It does not mean you have a temporary file, it just mean a sort is done (bad name, ignore the 4 first letters).
from Baron Schwartz: