2012-06-09 129 views
5

所以这里是一个非常简单的表格 'TBL':为什么这个简单的MySQL查询非常慢?

+---------+---------------------+------+-----+---------+----------------+ 
| 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'命令之后,它也可以快速完成。

+2

您可以尝试运行'EXPLAIN',但怀疑这是更多与服务器相关的问题。 –

+0

为什么要选择86个字段并且做两列?我认为这里的问题是查询的逻辑:/也许你应该分享你要实现的目标? –

+0

引擎?,请尝试全文索引 – jcho360

回答

3

没有真正检查你的服务器配置,很难说,但这是一个有教养的猜测。首先,MySQL能够在不实际读取表数据的情况下满足您的查询。您所要求的所有信息都可以从索引中单独检索。请注意,val索引的基数只有大约10 行的数量级,并且索引中的行将非常短。

在第二种情况下,您要求val索引中的数据NOT。现在引擎不得不从数据中找到并读取行。在这里,基数大约250倍,并且由于索引将检索按val排序的行,因此找到相应的值需要在磁盘上的数百个数据集中大量跳转。这将会非常慢。

+0

这就是原因。 – Sebas

+0

是的,正确的元组索引做到了。谢谢,请访问我的新问题:http://stackoverflow.com/questions/11004651/how-to-make-well-indexed-mysql-tables-join-effectively :) –

0

尝试向查询添加一个ORDER BY和“LIMIT”。这应该有很大的帮助。

我想如果你更改查询到这一点,会更快:

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

“限制”只会限制恢复的行数......它的速度更快,但如果您需要完整的数据集,则无用。另一方面,“order by”将减慢查询速度,因为服务器必须在发送数据之前对结果集进行排序 – Barranka

+0

排序会减慢查询速度 – jcho360

+0

@Barranka:假设他选择了所有行,是的。否则,他会选择一些随机行,数据库不知道如何优化。 – Wolph

0

您是根据两列做一个选择,但不存在这两个指标。尝试添加一个由组成的新索引 id和val。

+1

为什么当他只搜索val时他需要一个id索引? – gbjbaanb

相关问题