Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql文件排序即使使用索引也会发生--我如何修复_Mysql_Query Optimization - Fatal编程技术网

mysql文件排序即使使用索引也会发生--我如何修复

mysql文件排序即使使用索引也会发生--我如何修复,mysql,query-optimization,Mysql,Query Optimization,我在下面有一个简单的查询,我可以确保表运行得很快。我对查询做了解释,它说使用where;使用文件排序。有没有办法摆脱文件排序?数据现在只有大约25项;但最终可能会达到300或更多 mysql> show create table phppos_categories; +-------------------+--------------------------------------------------------------------------------------------

我在下面有一个简单的查询,我可以确保表运行得很快。我对查询做了解释,它说使用where;使用文件排序。有没有办法摆脱文件排序?数据现在只有大约25项;但最终可能会达到300或更多

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;