简体   繁体   English

是一种优化大型mysql查询的方法吗?

[英]Is a way to optimize big mysql query?

This is my query and it's to slow... I'm looking for the way to optimize it. 这是我的查询,而且很慢...我正在寻找优化方法。

SELECT p.id, 
       Group_concat(pc.cat_id)   AS groups, 
       p.code, 
       p.NAME, 
       p.price, 
       p.thumbnail, 
       p.image, 
       mc.queries                AS merch_queries, 
       mc.position               AS merch_position, 
       Group_concat(op.image)    AS option_images, 
       cf_RETAIL.value           AS custom_RETAIL, 
       cf_rating.value           AS custom_rating, 
       cf_reviews.value          AS custom_reviews, 
       cf_sku.value              AS custom_sku, 
       cf_brand.value            AS custom_brand, 
       cf_custom_thumbnail.value AS custom_custom_thumbnail 
FROM   s01_products AS p 
       LEFT JOIN s01_categoryxproduct AS pc 
              ON p.id = pc.product_id 
       LEFT JOIN (SELECT pv.product_id, 
                         pv.value 
                  FROM   s01_cfm_prodfields AS pf 
                         INNER JOIN s01_cfm_prodvalues AS pv 
                                 ON pf.id = pv.field_id 
                  WHERE  pf.code = 'RETAIL') AS cf_RETAIL 
              ON p.id = cf_RETAIL.product_id 
       LEFT JOIN (SELECT pv.product_id, 
                         pv.value 
                  FROM   s01_cfm_prodfields AS pf 
                         INNER JOIN s01_cfm_prodvalues AS pv 
                                 ON pf.id = pv.field_id 
                  WHERE  pf.code = 'rating') AS cf_rating 
              ON p.id = cf_rating.product_id 
       LEFT JOIN (SELECT pv.product_id, 
                         pv.value 
                  FROM   s01_cfm_prodfields AS pf 
                         INNER JOIN s01_cfm_prodvalues AS pv 
                                 ON pf.id = pv.field_id 
                  WHERE  pf.code = 'reviews') AS cf_reviews 
              ON p.id = cf_reviews.product_id 
       LEFT JOIN (SELECT pv.product_id, 
                         pv.value 
                  FROM   s01_cfm_prodfields AS pf 
                         INNER JOIN s01_cfm_prodvalues AS pv 
                                 ON pf.id = pv.field_id 
                  WHERE  pf.code = 'sku') AS cf_sku 
              ON p.id = cf_sku.product_id 
       LEFT JOIN (SELECT pv.product_id, 
                         pv.value 
                  FROM   s01_cfm_prodfields AS pf 
                         INNER JOIN s01_cfm_prodvalues AS pv 
                                 ON pf.id = pv.field_id 
                  WHERE  pf.code = 'brand') AS cf_brand 
              ON p.id = cf_brand.product_id 
       LEFT JOIN (SELECT pv.product_id, 
                         pv.value 
                  FROM   s01_cfm_prodfields AS pf 
                         INNER JOIN s01_cfm_prodvalues AS pv 
                                 ON pf.id = pv.field_id 
                  WHERE  pf.code = 'custom_thumbnail') AS cf_custom_thumbnail 
              ON p.id = cf_custom_thumbnail.product_id 
       LEFT JOIN (SELECT p.product_id          AS product_id, 
                         Group_concat(q.query) AS queries, 
                         Min(p.position)       AS position 
                  FROM   s01_srch_merchandisingproduct AS p 
                         LEFT JOIN s01_srch_merchandisingquery AS q 
                                ON q.id = p.query_id 
                  GROUP  BY p.product_id) AS mc 
              ON p.id = mc.product_id 
       LEFT JOIN s01_options AS op 
              ON p.id = op.product_id 
                 AND op.image <> '' 
WHERE  p.active = 1 
GROUP  BY p.id 

Thanks for any help! 谢谢你的帮助!

Updated Tables Schema: 更新的表架构:

**s01_categoryxproduct** 
cat_id, 
product_id, 
disp_order

**s01_products**
id      
catcount    
agrpcount   
pgrpcount   
disp_order  
code            
name            
thumbnail       
image           
price       
cost        
descrip         
weight      
taxable     
active      
sku         
cancat_id   
page_id     
page_title      
dt_created  
dt_updated

**s01_CFM_ProdValues** 
field_id, 
product_id, 
value, 
value_long

**s01_CFM_ProdFields** 
id, 
code, 
name, 
group_id, 
fieldtype, 
info, 
facet

**s01_Options** 
id, 
product_id, 
attr_id, 
disp_order, 
code, 
prompt, 
price, 
cost, 
weight, 
image

**s01_SRCH_MerchandisingProduct** 
id, 
product_id, 
query_id, 
position

**s01_SRCH_MerchandisingQuery** 
id, 
query

"Over-normalization" and EAV are the problems. 问题是“过度标准化”和EAV。

Put prodfields and prodvalues in the same table. 将prodfields和prodvalues放在同一张表中。 Splitting them into two tables leads to performance-eating overhead. 将它们分成两个表会导致性能降低的开销。

More on optimizing an EAV table: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta 有关优化EAV表的更多信息: http : //mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

More discussion of why EAV is bad: http://mysql.rjweb.org/doc.php/eav 有关为什么EAV不好的更多讨论: http : //mysql.rjweb.org/doc.php/eav

SELECT p.id, 
           Group_concat(pc.cat_id)   AS groups, 
           p.code, 
           p.NAME, 
           p.price, 
           p.thumbnail, 
           p.image, 
           mc.queries                AS merch_queries, 
           mc.position               AS merch_position, 
           Group_concat(op.image)    AS option_images, 
           IF(pf.code = 'RETAIL',pv.value , NULL)         AS custom_RETAIL,
           IF(pf.code = 'rating',pv.value , NULL)         AS custom_rating, 
           IF(pf.code = 'reviews',pv.value , NULL)         AS custom_reviews, 
           IF(pf.code = 'brand',pv.value , NULL)         AS custom_brand, 
           IF(pf.code = 'custom_thumbnail',pv.value , NULL)         AS custom_custom_thumbnail, 
           pvr.value           AS custom_rating, 
    FROM   s01_products AS p 
    LEFT JOIN s01_categoryxproduct AS pc ON p.id = pc.product_id 
    LEFT JOIN s01_cfm_prodfields AS cf_RETAIL ON p.id = cf_RETAIL.product_id 
    LEFT JOIN s01_cfm_prodvalues AS pv ON cf_RETAIL.id = pv.field_id
    LEFT JOIN (SELECT p.product_id          AS product_id, 
                         Group_concat(q.query) AS queries, 
                         Min(p.position)       AS position 
                  FROM   s01_srch_merchandisingproduct AS p 
                         LEFT JOIN s01_srch_merchandisingquery AS q 
                                ON q.id = p.query_id 
                  GROUP  BY p.product_id) AS mc 
              ON p.id = mc.product_id 
       LEFT JOIN s01_options AS op 
              ON p.id = op.product_id 
                 AND op.image <> ''
    WHERE  p.active = 1
    GROUP  BY p.id`;

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

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