如何让这个MySQL查询表现更好?

时间:2011-02-11 19:49:15

标签: mysql performance

我有一个查询阻止我使用此应用程序,因为在未缓存时最多可能需要7秒才能完成。

SELECT attribute1
FROM `product_applications`
WHERE `product_applications`.`brand_id` IN (.. like 500 ids...)
GROUP BY attribute1

我将brand_id编入索引。我以前做过SELECT DISTINCT,但选择了GROUP BY,性能略有提升。

此表使用的是InnoDB,大约有230万行。我已经对它运行了一个EXPLAIN,它使用索引,它只需要永远。

我知道有很多变量可以让这样的事情发挥作用。数据库位于Amazon EC2实例上。

我是否可以进行某种表拆分以使查询更好地执行?我非常感谢任何人提供的任何帮助。

编辑:

以下是我的解释结果,来自NewRelic:

Id  1
Select Type SIMPLE
Table   product_applications
Type    range
Possible Keys   brand_search_index_1,brand_search_index_2,brand_search_index_3,brand_search_index_4,brand_sarch_index_5
Key brand_search_index_1
Key Length  5
Ref 
Rows    843471
Extra   Using where; Using index; Using temporary; Using filesort

看,它正在使用索引。但它也使用临时表和filesort。我怎么能克服这些东西?

编辑:

自从我打开这个问题以来,我将此表上的引擎从InnoDB更改为MyISAM。我还通过将属性5到60移动到另一个表来垂直分区表。但这个选择声明仍然在2到3秒之间!这个查询的糟糕表现绝对令人抓狂。

4 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

如果attribute1的{​​{1}} i的差异非常少,可以使用attribute1上的索引来利用loose index scan

答案 2 :(得分:0)

根据this answer IN在常量情况下应该非常快,否则会发生类型转换,从而导致事情变慢。

我还会尝试将covering index作为第一列使用brand_id,将第一列作为第一列。这样可以加快速度,因为你的桌子不再被访问了。

编辑:

关于临时/ filesort,我怀疑它们是由你的+500 ID列表引起的。你能在IN运算符中只有一个id的查询上尝试EXPLAIN吗?

答案 3 :(得分:0)

如果您可以减少可能有用的行的大小。尽可能多的列不为空。如果您可以删除所有可能有用的varchar列。

它使用封面的索引究竟是什么?可能会尝试使索引覆盖更少或更多的列。

你最近跑过分析表吗?这可能会导致它选择另一个指数。您也可以尝试强制使用某些索引。

是否有可能减少IN子句中的id数量?如果使用范围,如果它们始终是顺序ID,那该怎么办?