2014-02-15 58 views
0

我们有一家电子商店,在这个电子商店中,类别和产品之间有许多复杂的联系。缓慢的Mysql查询,3个左连接

我正在使用分类标准表来存储产品 - 类别和产品 - 产品之间的关系作为子产品。

产品可能是多个类别的成员。 产品可能是其他产品的子产品。 (可能多于一个) 产品可以是其它产品的模块(可能多于一个)的查询的

别名: PR-产品 CT-类别 SP-子产品 MD-模块

Select pr.*,ifnull(sp.destination_id,0) as `top_id`, 
    ifnull(ct.destination_id,0) as `category_id` 
from Products as pr 
Left join Taxonomy as ct 
    on (ct.source_id=pr.id and ct.source='Products' and ct.destination='Categories') 
Left join Taxonomy as sp 
    on (sp.source_id=pr.id and sp.source='Products' and sp.destination='Products' and sp.type='TOPID') 
Left join Modules as md 
    on(pr.id = md.product_id) 
where pr.deleted=false 
    and ct.destination_id='47' 
    and sp.destination_id is null 
    and md.product_id is null 
order by pr.order,pr.sub_order 

使用此查询;我试图让所有产品在Category_id = 47下,而不是任何产品的模块,也不是任何产品的子产品。

此查询需要23秒。 产品中有7.820条记录,模块中有3.200条记录,分类标准有19.000条记录

回答

0

我想说的是,MySQL只能对每个查询使用一个索引,但看起来不再是这种情况。我也遇到了另一个答案: http://dev.mysql.com/doc/mysql/en/index-merge-optimization.html

但是,这可能不会帮助你。

过去,当我遇到查询时MySQL无法优化我已经解决了使用后台作业在另一个表中预计算答案的问题。

你想要做的事看起来很适合像neo4j这样的图形数据库。

0

MySQL的优化器自动更改外部到内部联接是不好的,它首先执行外部联接,然后开始过滤数据。

在你的情况下,Products和Taxonomy之间的连接可以被重写为一个Inner Join(在ct.destination_id = '47'处有一个WHERE条件)。

如果这改变了执行计划并提高了性能,请尝试。