我们有一个电子商店,在这个电子商店中,类别和产品之间有许多复杂的链接。
我正在使用Taxonomy表来存储Products-Categories和Products-Products之间的关系作为子产品。
产品可能是多个类别的成员。 产品可以是子产品,是其他产品的子产品。 (可能不止一个) 产品可能是其他产品的模块(可能不止一个)
查询的别名: PR-产品 CT-类别 sp-Sub产品 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 :(得分:0)
我打算说MySQL每个查询只能使用一个索引,但看起来不再是这种情况了。我还在另一个答案中看到了这个: http://dev.mysql.com/doc/mysql/en/index-merge-optimization.html
然而,这可能对您没有帮助。
过去,当我遇到查询MySQL无法优化时,我已决定使用后台作业在另一个表中预先计算答案。
你想要做的事情看起来非常适合像neo4j这样的图形数据库。
答案 1 :(得分:0)
众所周知,MySQL的优化器在自动更改外部连接到内部连接时很糟糕,它首先执行外部连接,然后开始过滤数据。
在您的情况下,Products和Taxonomy之间的连接可以重写为Inner Join(在ct.destination_id ='47'上有一个WHERE条件)。
尝试更改执行计划并提高性能。