多个左连接和性能

时间:2012-02-22 07:30:45

标签: mysql

我有以下表格:

产品 - 4500条记录

字段:id,sku,名称,别名,价格,special_price,数量,desc,照片,manufacturer_id,model_id,点击,发布

products_attribute_rel - 35000条记录

字段:id,product_id,attribute_id,attribute_val_id

attribute_values - 243条记录

字段:id,attr_id,值,排序

制造商 - 29条记录

字段:id,title,publishing

模特 - 946条记录

字段:id,manufacturer_id,title,publishing

所以我通过一个查询从这些表中获取数据:

SELECT jp.*,
       jm.id AS jm_id,
       jm.title AS jm_title,
       jmo.id AS jmo_id,
       jmo.title AS jmo_title
FROM `products` AS jp 
LEFT JOIN `products_attribute_rel` AS jpar ON jpar.product_id = jp.id
LEFT JOIN `attribute_values` AS jav ON jav.attr_id = jpar.attribute_val_id
LEFT JOIN `manufacturers` AS jm ON jm.id = jp.manufacturer_id
LEFT JOIN `models` AS jmo ON jmo.id = jp.model_id 
GROUP BY jp.id HAVING COUNT(DISTINCT jpar.attribute_val_id) >= 0 

这个查询很慢。处理它需要数百秒的mysql。 那么如何才能改进这个查询呢?使用小数据块可以正常工作 非常好。但我想一切都是废墟products_attribute_rel表,哪个 有35000条记录。

我们将不胜感激。

EDITED

EXPLAIN查询的

SELECT结果:

EXPLAIN results of the SELECT query

3 个答案:

答案 0 :(得分:9)

问题是MySQL对3个表使用了连接类型ALL。这意味着MySQL执行3次全表扫描,将所有可能性放在一起,然后再排除那些与ON语句不匹配的内容。要获得更快的连接类型(例如eq_ref),必须在ON语句上使用的coloumns上添加索引。

请注意,不建议在每个可能的coloumn上添加索引。许多索引会加速SELECT语句,但是它也会产生开销,因为必须存储和管理索引。这意味着像UPDATEDELETE这样的操纵查询要慢得多。我看到查询在半小时内只删除了1000条记录。这是一个权衡,你必须决定更频繁发生什么,更重要的是什么。

要获得有关MySQL连接类型的更多信息,请查看this 有关索引here的更多信息。

答案 1 :(得分:1)

表数据并不是那么庞大,需要数百秒。表模式有问题。请做正确的索引。那将会加速。

答案 2 :(得分:0)

select distinct
jm.id AS jm_id,
jm.title AS jm_title,
jmo.id AS jmo_id,
jmo.title AS jmo_title
from products jp, 
products_attribute_rel jpar,
attribute_values jav,
manufacturers jm
models jmo
where jpar.product_id = jp.id
and jav.attr_id = jpar.attribute_val_id
and jm.id = jp.manufacturer_id
and jmo.id = jp.model_id

如果要选择所有数据,可以这样做。希望它有效。