简体   繁体   English

使用DISTINCT优化​​mysql查询供应商<->产品<->类别

[英]Optimize mysql query Suppliers <-> Products <-> Categories with DISTINCT

My DB is like this: Products are N:N to Categories so there is a join table (products_categories). 我的数据库是这样的:产品对类别是N:N,因此有一个联接表(products_categories)。 Products have a Supplier (1 and only 1), so Products table have a supplier_id. 产品有一个供应商(1个,只有1个),因此“产品”表中有一个Supplier_id。 Products are about 500K, categories about 200 and suppliers about 80. 产品约500,000,类别约200,供应商约80。

Right now I want to get the Distinct suppliers for Products with status = 1 and in categories 2,3 and 125. 现在,我想获得状态为1且类别为2,3和125的“产品”的不同供应商。

My SQL: 我的SQL:

SELECT DISTINCT s.id FROM suppliers s INNER JOIN products AS p ON p.supplier_id = s.id INNER JOIN products_categories AS pc ON p.id = pc.products_id WHERE (p.color IN ('red', 'blue')) AND pc.categories_id IN (2,3,125) 从供应商处选择不同的s.id内联products as p ON p.supplier_id = s.id内联products_categories product_categories AS pc ON p.id = pc.products_id WHERE(p.color IN(“红色”,“蓝色”)) AND pc.categories_id IN(2,3,125)

The problem with the query is the distinct. 查询的问题是独特的。 Without it the query returns in about 1 second, with DISTINCT it takes about 3 seconds. 没有它,查询将在大约1秒钟后返回,而DISTINCT则需要大约3秒钟。 I have indexes for all FK's / PK. 我有所有FK / PK的索引。

Explain plan: 说明计划:

id  select_type table   type    possible_keys           key         key_len ref             rows    Extra
1   SIMPLE      pc      range   products_id,categories  categories  4       NULL            28335   Using where; Using temporary
1   SIMPLE      p       eq_ref  PRIMARY,color           PRIMARY     4       pc.products_id      1   Using where
1   SIMPLE      s       eq_ref  PRIMARY                 PRIMARY     4       p.supplier_id       1   Using where; Using index

Adding the distinct adds that "Using temporary" to the explain query plan. 添加非重复项将在解释查询计划中添加“使用临时”。

So, is there any way to optimize this query? 那么,有什么方法可以优化此查询? How to do this distinct in a better way (schema changes are also welcomed if needed) 如何更好地做到这一点(如有需要,还可以更改模式)

Have you tried using an EXISTS ? 您是否尝试过使用EXISTS

Something like 就像是

SELECT  s.id 
FROM    suppliers s 
WHERE   EXISTS  (
                    SELECT  1
                    FROM    products AS p INNER JOIN 
                            products_categories AS pc ON p.id = pc.products_id 
                    WHERE   (p.supplier_id = s.id)
                    AND     (p.color IN ('red', 'blue')) 
                    AND     pc.categories_id IN (2,3,125)
                )

Try GROUP BY instead of DISTINCT : 尝试GROUP BY而不是DISTINCT

SELECT s.id 
FROM suppliers s 
INNER JOIN products AS p ON p.supplier_id = s.id AND p.color IN ('red', 'blue')
INNER JOIN products_categories AS pc USE INDEX (combined_index_name) ON p.id = pc.products_id AND pc.categories_id IN (2,3,125)
GROUP BY s.id 

EDIT 编辑

Create a combine index on products_id & categories_id columns of products_categories table. products_id表的products_categoriescategories_id列上创建一个合并索引。 Then check the performance of query. 然后检查查询的性能。

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

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