mysql文件排序即使使用索引也会发生--我如何修复
我在下面有一个简单的查询,我可以确保表运行得很快。我对查询做了解释,它说使用where;使用文件排序。有没有办法摆脱文件排序?数据现在只有大约25项;但最终可能会达到300或更多mysql文件排序即使使用索引也会发生--我如何修复,mysql,query-optimization,Mysql,Query Optimization,我在下面有一个简单的查询,我可以确保表运行得很快。我对查询做了解释,它说使用where;使用文件排序。有没有办法摆脱文件排序?数据现在只有大约25项;但最终可能会达到300或更多 mysql> show create table phppos_categories; +-------------------+--------------------------------------------------------------------------------------------
mysql> show create table phppos_categories;
+-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_categories | CREATE TABLE `phppos_categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `phppos_categories_ibfk_1` (`parent_id`),
KEY `name` (`name`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `phppos_categories_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `phppos_categories` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM (`phppos_categories`) WHERE `parent_id` = 5 ORDER BY `name` asc;
+----+-----------+-------------------+
| id | parent_id | name |
+----+-----------+-------------------+
| 3 | 5 | Basketball Shoes |
| 7 | 5 | Basketball Shorts |
+----+-----------+-------------------+
2 rows in set (0.00 sec)
mysql> EXPLAIN SELECT * FROM (`phppos_categories`) WHERE `parent_id` = 5 ORDER BY `name` asc;
+----+-------------+-------------------+------+------------------------------------+--------------------------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------------+------+------------------------------------+--------------------------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | phppos_categories | ref | phppos_categories_ibfk_1,parent_id | phppos_categories_ibfk_1 | 5 | const | 2 | Using where; Using filesort |
+----+-------------+-------------------+------+------------------------------------+--------------------------+---------+-------+------+-----------------------------+
1 row in set (0.00 sec)
mysql>
您看到的是“使用文件排序”,因为您是按
name
列排序的,该列是一个varchar(255)字段
解释报告中所检查的记录数仅为2,并且正在使用父\u id上的索引。结果集中有2行。因此,MySQL没有做任何额外或不必要的工作
就我个人而言,在这种情况下,我不会担心如何摆脱“使用文件排序”。即使表中有300行,您仍在使用索引字段(parent_id)上的where限制结果集,并且检查的行数将等于结果集中的行数 您可以通过在(parent_id,name)上添加多列索引来删除此处的文件排序 更改表
phppos\u类别添加索引(parent\u id
,name
)
一般来说,当MySQL需要对其中一个索引进行排序时,它只会使用一个索引(如果您只是简单地使用两个索引来查询表,它可能会使用索引合并来使用两个索引,但通常情况并非如此)。解决方案是创建一个索引,覆盖需要查询的所有列
其次,MySQL只能对其使用的索引中的最后一列进行“范围”搜索或“排序”。在此之前的任何列都必须是完全相等的匹配
在此基础上,我们可以先创建一个具有parent_id的索引,该索引具有精确的相等匹配(=5),然后创建一个名,该名是您的订单约束
需要注意的主要一点是,您不希望添加超过必要数量的索引,而适合每一个可能的查询的索引可能并不明智,特别是考虑到保持索引最新所需的额外存储空间和工作量。作为比较的一部分,您还需要考虑更新表的频率。如果很少更新,那么更多的索引可能就不太成问题了
有关更多信息,请参见此处:
ORDER BY `name` asc;