为什么这个简单的MySQL查询如此之慢?

时间:2012-06-09 20:19:55

标签: mysql performance indexing where

所以这是一个非常简单的表'tbl':

+---------+---------------------+------+-----+---------+----------------+
| Field   | Type                | Null | Key | Default | Extra          |
+---------+---------------------+------+-----+---------+----------------+
| val     | varchar(45)         | YES  | MUL | NULL    |                |
| id      | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
+---------+---------------------+------+-----+---------+----------------+

它的索引:

+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tbl    |          0 | PRIMARY  |            1 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
| tbl    |          1 | val      |            1 | val         | A         |      881336 |     NULL | NULL   | YES  | BTREE      |         |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

我正在尝试这个简单的选择:

select val from tbl where val = 'iii';

结果:86208行(0.08秒)

但是当我想略微修改它时:

select id, val from tbl where val = 'iii';

结果是:86208行(47.30秒)

我在coumn上有一个索引,指向的地方,我正在修改的是结果行表示。 为什么有如此可怕的延迟? (我不得不说每次我都不能重现这种延迟:即使在'重置查询缓存'或设置'query_cache_type = off'命令后,也可以快速完成)。

3 个答案:

答案 0 :(得分:3)

如果没有实际检查您的服务器配置,很难说,但这是一个有根据的猜测。在第一个实例中,MySQL能够满足您的查询而无需实际读取表数据。您所要求的所有信息都可以单独从索引中检索。请注意,val索引的基数仅为10 6 行的顺序,并且索引中的行将非常短。

在第二种情况下,您要求val上的索引中没有数据。现在引擎必须实际查找和读取数据中的行。这里的基数大约是250倍,并且由于索引将检索由val排序的行,因此找到相应的id值将需要在磁盘上的数百个数据中跳转。这将会非常慢。

答案 1 :(得分:0)

尝试向查询添加ORDER BY和`LIMIT。这应该会有很大帮助。

我认为如果您将查询更改为此更快:

select id, val from tbl where val = 'iii' order by val limit 10;

答案 2 :(得分:0)

您正在基于两列进行选择,但两者都没有索引。尝试添加由两者 id和val。

组成的新索引
相关问题