为什么这个查询需要这么长时间?

问题描述:

此查询出现在我的慢日志MySQL的系统上,为什么这个查询需要这么长时间?

# Query_time: 37 Lock_time: 0 Rows_sent: 5 Rows_examined: 405199 
select euroapps.id, euroapps.name, euroapps.imageurl, euroapps.created, 
application_price.retail_price, euroapps.count FROM application_price INNER JOIN 
euroapps ON euroapps.id = application_price.application_id WHERE 
application_price.storefront_id = '143441' AND application_price.retail_price <= 0 
ORDER BY created DESC LIMIT 5; 

你看它检查405199行,算得上是长查询时间的原因是什么?

类似的查询我慢日志一直没有出现,查询是:

select euroapps.id, euroapps.name, euroapps.imageurl, euroapps.created, 
application_price.retail_price, euroapps.count FROM application_price INNER JOIN 
euroapps ON euroapps.id = application_price.application_id WHERE 
application_price.storefront_id = '$store' AND application_price.retail_price > 0 
ORDER BY created DESC LIMIT 5 

这里是输出解释:

mysql> explain select euroapps.id, euroapps.name, euroapps.imageurl, euroapps.created, application_price.retail_price, euroapps.count FROM application_price INNER JOIN euroapps ON euroapps.id = application_price.application_id WHERE application_price.storefront_id = '143441' AND application_price.retail_price <= 0 ORDER BY created DESC LIMIT 5; 
+----+-------------+-------------------+--------+----------------------------------+--------------------------+---------+---------------------------------------------+--------+-----------------------------------------------------------+ 
| id | select_type | table    | type | possible_keys     | key      | key_len | ref           | rows | Extra              | 
+----+-------------+-------------------+--------+----------------------------------+--------------------------+---------+---------------------------------------------+--------+-----------------------------------------------------------+ 
| 1 | SIMPLE  | application_price | range | PRIMARY,idx_storedfront_price_id | idx_storedfront_price_id | 9  | NULL          | 110491 | Using where; Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | euroapps   | eq_ref | PRIMARY       | PRIMARY     | 4  | itunesapps.application_price.application_id |  1 |               | 
+----+-------------+-------------------+--------+----------------------------------+--------------------------+---------+---------------------------------------------+--------+-----------------------------------------------------------+ 
2 rows in set (0.00 sec) 
+2

如果你还没有它们,我会把索引放在'application_price.application_id','application_price.storefront_id'和'application_price.retail_price'上。 – 2011-05-17 14:24:49

+0

@Jason只是写了同样的东西:)。另外,'application_price.retail_price'列的数据类型是什么?如果该值可能低于零,请确保它是数字,*不是*无符号 – Phil 2011-05-17 14:26:42

+0

您可能还想调整MySQL的内存设置。我想,虽然我不能肯定,认为“使用临时;使用文件排序”意味着MySQL正在建立某种硬盘上的临时文件,以尽自己的排序,而它可能在RAM中做这种正确的如果内存配置允许它这样做。不要在此引用我的意见,但最近我遇到了类似的问题,并增加了可用的内存以解决问题。 – 2011-05-17 14:27:13

你应该看看执行计划,即将有助于缩小原因。 http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html

查看您的WHERE子句,可以看到您使用application_price.storefront_id作为过滤因子。 但是,在您的EXPLAIN中,它并不是可能的关键含义,因为它没有被索引 - 这意味着需要全表扫描。

另一个因素是application_price.retail_price,you can see what RANGE in explain means - 但它的基数显然很低 - 因此很多行。

正如Jason Swett建议的那样 - 索引您的application_price.storefront_id并且您应该看到更好的性能(并且Jason您应该将您的评论发布为答案)。

解释的“rows”列指示MySQL简单化它将不得不从application_price表中检查110491行。它也是使用临时的;在此表上使用filesort。

如果“created”是application_price的字段,我建议您为application_price添加一个包含(storefront_id,application_id,retail_price,created)的索引。索姆这些领域的组合应该有所帮助。