我的mySQL表的排序不使用索引,我不知道为什么.
我有:
CREATE TABLE IF NOT EXISTS `test` (
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
KEY `kk` (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
还有这个:
EXPLAIN SELECT *
FROM test
ORDER BY a
Run Code Online (Sandbox Code Playgroud)
以及这个
EXPLAIN SELECT *
FROM test
USE INDEX ( kk )
ORDER BY a
Run Code Online (Sandbox Code Playgroud)
给我这个:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE test ALL NULL NULL NULL NULL 10009 Using filesort
Run Code Online (Sandbox Code Playgroud)
我不想看到这个文件,并使用密钥kk对我的表进行排序.我究竟做错了什么?
谢谢你的帖子,他们回答我的问题!但是,现在我不明白"table scan"和"filesort"的含义是什么?即使我选择了表的所有字段和所有行,通过在O(n)中遍历该列索引的内部树(然后在表中查找)来将该表排序为一列不是更快文件所请求的额外列,在O(1)中为每一行=>索引文件存储每个行在表文件中的物理位置,或?),而不是排序,例如通过快速排序在O(n*log n)中(可能)在表文件中随机存储行,而不触及索引?我想我对mySQL如何在mySQL中工作的理解是错误的.
@zerkms是正确的,通过读取表中的所有行,MySQL决定无论如何都必须读取表的大部分,因此也无需读取索引。如果选择表的子集,则优化器会更改行为。
例如,我创建了一个像您一样的表,并用16384行填充它,并使用介于0和1000000之间的随机整数。然后我尝试对表的不同子集尝试EXPLAIN,首先是表的15%,然后是17%,然后是19%。
mysql> EXPLAIN SELECT * FROM test where a < 150000 ORDER BY a;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test | range | kk | kk | 5 | NULL | 2272 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
mysql> EXPLAIN SELECT * FROM test where a < 170000 ORDER BY a;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test | range | kk | kk | 5 | NULL | 2560 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
mysql> EXPLAIN SELECT * FROM test where a < 190000 ORDER BY a;
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | test | ALL | kk | NULL | NULL | NULL | 16384 | Using where; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+-------+-----------------------------+
Run Code Online (Sandbox Code Playgroud)
您也可以通过减少列数直到它只是选择索引的列来说服它使用索引。它将决定仅读取索引,而不要触摸表格。您可以根据需要定义带有额外列的索引,即使搜索或排序不需要这些列。
mysql> ALTER TABLE test ADD KEY kk2 (a,b);
mysql> EXPLAIN SELECT a,b FROM test ORDER BY a;
+----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | test | index | NULL | kk2 | 10 | NULL | 16384 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+-------+-------------+
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17582 次 |
| 最近记录: |