为什么MySQL在快速子查询上选择count(*)这么慢?

时间:2016-02-02 19:53:07

标签: mysql performance

我有以下快速执行的查询:

SELECT DISTINCT p.products_id, 
                p.products_image, 
                p.products_quantity, 
                p.products_status, 
                m.manufacturers_id, 
                p.products_date_added, 
                p.products_subimage1, 
                pd.products_name, 
                p.products_price, 
                p.products_length, 
                p.products_width, 
                p.products_height, 
                p.products_tax_class_id, 
                IF(s.status, s.specials_new_products_price, NULL)             AS 
                specials_new_products_price, 
                IF(s.status, s.specials_new_products_price, p.products_price) AS 
                final_price,
                IF(clearance_price < products_cost * 2.25, 
                clearance_price, 
                products_cost * 2.25)                                       AS 
                sorting_price 

FROM   

       (SELECT products_id ,
                IF(clearance_price < products_cost * 2.25, 
                clearance_price, 
                products_cost * 2.25)                                       AS 
                sorting_price 
                FROM `products` 
                ORDER BY products_id DESC)q,


       products p
       left join manufacturers m USING(manufacturers_id) 
       left join specials s 
              ON p.products_id = s.products_id 
       left join products_attributes pa 
              ON p.products_id = pa.products_id 
       left join products_options po 
              ON pa.options_id = po.products_options_id 
       left join products_options_values pov 
              ON pa.options_values_id = pov.products_options_values_id, 
       products_description pd, 
       categories c, 
       products_to_categories p2c 
WHERE  

       q.products_id = p.products_id 
       AND q.sorting_price = sorting_price
       AND 

       p.products_status = '1' 
       AND p.products_id = pd.products_id 
       AND pd.language_id = '1' 
       AND p.products_id = p2c.products_id 
       AND p2c.categories_id = c.categories_id 
       AND (( pd.products_name LIKE '%a%' 
               OR po.products_options_name LIKE '%a%' 
               OR pov.products_options_values_name LIKE '%a%' 
               OR pd.products_description LIKE '%a%' ))

当我将它包装在count(*)查询中时,新的计数查询需要10到15倍的时间,非常慢。 我像这样包装它:

SELECT count(*) as total from (
    SELECT DISTINCT p.products_id, 
                p.products_image, 
                p.products_quantity, 
                p.products_status, 
                m.manufacturers_id, 
                p.products_date_added, 
                p.products_subimage1, 
                pd.products_name, 
                p.products_price, 
                p.products_length, 
                p.products_width, 
                p.products_height, 
                p.products_tax_class_id, 
                IF(s.status, s.specials_new_products_price, NULL)             AS 
                specials_new_products_price, 
                IF(s.status, s.specials_new_products_price, p.products_price) AS 
                final_price,
                IF(clearance_price < products_cost * 2.25, 
                clearance_price, 
                products_cost * 2.25)                                       AS 
                sorting_price 

FROM   

       (SELECT products_id ,
                IF(clearance_price < products_cost * 2.25, 
                clearance_price, 
                products_cost * 2.25)                                       AS 
                sorting_price 
                FROM `products` 
                ORDER BY products_id DESC)q,


       products p
       left join manufacturers m USING(manufacturers_id) 
       left join specials s 
              ON p.products_id = s.products_id 
       left join products_attributes pa 
              ON p.products_id = pa.products_id 
       left join products_options po 
              ON pa.options_id = po.products_options_id 
       left join products_options_values pov 
              ON pa.options_values_id = pov.products_options_values_id, 
       products_description pd, 
       categories c, 
       products_to_categories p2c 
WHERE  

       q.products_id = p.products_id 
       AND q.sorting_price = sorting_price
       AND 

       p.products_status = '1' 
       AND p.products_id = pd.products_id 
       AND pd.language_id = '1' 
       AND p.products_id = p2c.products_id 
       AND p2c.categories_id = c.categories_id 
       AND (( pd.products_name LIKE '%a%' 
               OR po.products_options_name LIKE '%a%' 
               OR pov.products_options_values_name LIKE '%a%' 
               OR pd.products_description LIKE '%a%' ))
    ) AS derivedtable1

为什么会这样?有没有办法优化这个?

修改 这是第一个查询的EXPLAIN EXTENDED: enter image description here

这是count(第二个)查询的EXPLAIN EXTENDED: enter image description here

这是第一个查询的PROFILING: enter image description here

这是count(第二个)查询的PROFILING: enter image description here

1 个答案:

答案 0 :(得分:0)

FROM pd
LEFT JOIN po ON ...
WHERE ( ... OR po.x LIKE '...' OR ... )

LEFT的语义表示po中是否存在匹配行并不重要。因此LIKE对查询结果没有任何影响。建议你摆脱OR ... LIKE中任何项目的LEFT。或许你真的不是指LEFT?那个可以让它运行得更快,但结果集可以不同。

我从EXPLAINs看到没有充分理由说明时间差异。哦,你是如何运行查询的?第一个有213K行的输出 - 你是否在等待所有它返回才停止你的秒表?