MySQL对多个表进行排序需要很长时间

时间:2011-05-19 06:41:26

标签: mysql sql sql-order-by

我有一个包含对象和相关表的表table_info,object_theme(类别),位置和对象所有者。

我想要的是首先显示具有更高优先级的对象所有者的所有对象,然后显示其余对象。所以我的查询类似于以下内容:

SELECT 
   (...)
FROM objects
INNER JOIN object_info ...
INNER JOIN objectowner_info ...
INNER JOIN locations ...
WHERE object_active = 1
  AND object_owner_active = 1
ORDER BY object_owner_priority DESC,
         object_price ASC
   LIMIT 0, 10

正如您所看到的,我选择了所有对象,并将具有更高优先级状态的对象所有者的对象赋予首先显示的边缘。然后从最低价格排序。但大多数时候这个查询都非常慢。

优化此查询的最佳步骤是什么?我尝试了各种各样的索引,但瓶颈似乎是排序。当我把它拿出来时,查询速度可以正常。

(请注意我没有加入主题(类别),我正在考虑以不同的方式实现这一点,因为您需要对结果进行分组的1:n关系,而且这看起来非常慢。联接中提到的其他表格具有1:1的关系。)。

比较:排序中没有两列的查询需要0.0011秒。上面提到的两个列都是0.8779。但是根据负载,它可能需要几秒钟。


EXPLAIN with sorting:

id  select_type     table   type    possible_keys                                       key                 key_len     ref             rows    Extra
1   SIMPLE          o       ALL     PRIMARY,fk_object_user,fk_object_city,type active   NULL                NULL        NULL            63773   Using where; Using temporary; Using filesort
1   SIMPLE          ooi     ref     fk_objectowner_id                                   fk_objectowner_id   4           o.object_user   1       Using where
1   SIMPLE          oo      eq_ref  PRIMARY,id_and_status                               PRIMARY             4           o.object_user   1       Using where
1   SIMPLE          l       eq_ref  PRIMARY                                             PRIMARY             4           o.object_city   1       Using where
1   SIMPLE          oi      ref     fk_info_lang,fk_info_object,lang_object             fk_info_object      3           o.object_id     1       Using where

没有排序的EXPLAIN:

id  select_type     table   type    possible_keys                                       key                 key_len     ref             rows    Extra
1   SIMPLE          o       ALL     PRIMARY,fk_object_user,fk_object_city,type active   NULL                NULL        NULL            63773   Using where
1   SIMPLE          ooi     ref     fk_objectowner_id                                   fk_objectowner_id   4           o.object_user   1   Using where
1   SIMPLE          oo      eq_ref  PRIMARY,id_and_status                               PRIMARY             4           o.object_user   1   Using where
1   SIMPLE          l       eq_ref  PRIMARY                                             PRIMARY             4           o.object_city   1   Using where
1   SIMPLE          oi      ref     fk_info_lang,fk_info_object,lang_object             fk_info_object      3           o.object_id     1   Using where

2 个答案:

答案 0 :(得分:0)

在object_owner_priority和object_price上定义索引,并将where子句更改为:

WHERE object_active + 0 = 1
  AND object_owner_active + 0 = 1

任何运气应该可以解决问题。如果已在object_active或object_owner_active上定义了索引,请考虑删除它们。

答案 1 :(得分:0)

嗯,现在通过创建单独的订单列并通过cron作业填充它们来解决问题,该作业每隔一段时间执行一次慢速查询以生成所需订单。