简体   繁体   English

慢的MySQL查询,还有3个左联接

[英]Slow Mysql Query with 3 left join

We have a e-store and in this e-store there is many complicated links between categories and products. 我们有一个电子商店,在这个电子商店中,类别和产品之间存在许多复杂的链接。

I'm using Taxonomy table in order to store relations between Products-Categories and Products-Products as sub product. 我使用分类表来存储产品-类别和产品-产品之间的关系作为子产品。

Products may be member of more than one category. 产品可能属于多个类别。 Products may be a sub product a sub product of an other product. 产品可以是子产品,也可以是其他产品的子产品。 (May be more than one) Products may be a module of an other product (May be more than one) (可能不止一个)产品可能是另一个产品的模块(可能不止一个)

aliases of query : pr-Product ct-Category sp-Sub Product md-Module 查询别名: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

With this query; 有了这个查询; I'm trying to get all products under Category_id=47 and not module of any product and not sub product of any product. 我正在尝试将所有产品归为Category_id = 47,而不是任何产品的模块,而不是任何产品的子产品。

This query takes 23 seconds. 此查询需要23秒。 There is 7.820 Records in Products, 3.200 Records in Modules and 19.000 records in Taxonomy 产品中有7.820条记录,模块中有3.200条记录,分类法中有19.000条记录

I was going to say that MySQL can only use one index per query but it looks like that is no longer the case. 我要说的是,MySQL每个查询只能使用一个索引,但是现在看来情况已不再如此。 I also came across this in another answer: http://dev.mysql.com/doc/mysql/en/index-merge-optimization.html 我也在另一个答案中遇到了这个问题: http : //dev.mysql.com/doc/mysql/en/index-merge-optimization.html

However that may not help you. 但是,这可能对您没有帮助。

In the past, when I've come across queries MySQL couldn't optimised I've settled for precomputing answers in another table using a background job. 过去,当我遇到无法优化MySQL的查询时,我就决定使用后台作业在另一个表中预先计算答案。

What you're trying to do looks like a good fit for a graph database like neo4j. 您正在尝试做的事情看起来非常适合像neo4j这样的图形数据库。

MySQL's optimizer is known to be bad in changing Outer to Inner joins automatically, it does the outer join first and then starts to filter data. 众所周知,MySQL的优化器不利于自动将外部联接更改为内部联接,它先执行外部联接,然后开始过滤数据。

In your case the join between Products and Taxonomy can be rewritten as an Inner Join (there's a WHERE-condition on ct.destination_id='47'). 在您的情况下,产品和分类法之间的联接可以重写为内部联接(ct.destination_id = '47'上存在WHERE条件)。

Try if this changes the execution plan and improves performance. 请尝试这是否会改变执行计划并提高性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM