mysql单表SELECT查询ORDER BY导致FILESORT

发布于 2024-11-15 23:12:16 字数 1500 浏览 2 评论 0原文

我浏览了多个类似的帖子,试图获取有关如何重新定义索引的信息,但无法弄清楚这一点。每次我包含 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

童话 2024-11-22 23:12:16

为什么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 or composite 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 field isactive 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

谜兔 2024-11-22 23:12:16

在 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:

The truth is, filesort is badly named. Anytime a sort can’t be performed from an index, it’s a filesort. It has nothing to do with files. Filesort should be called “sort.” It is quicksort at heart.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文