以下是sql,程序执行此处CPU一直在100%,非常占用资源,请问谁有好的办法优化 SELECT p.*, pa.`id_product_attribute`, pl.`description`, pl.`description_short`,
pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, i.`id_image`, il.`legend`,m.`name` AS manufacturer_name,
tl.`name` AS tax_name, t.`rate`, cl.`name` AS category_default, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL 3 DAY)) > 0 AS new, (p.price - IF((DATEDIFF(reduction_from, CURDATE()) <= 0 AND DATEDIFF(reduction_to, CURDATE()) >=0) OR reduction_from = reduction_to, IFNULL(reduction_price, (p.price * reduction_percent / 100)),0)) AS orderprice FROM `ps_category_product` cpLEFT JOIN `ps_product` p ON p.`id_product` = cp.`id_product` LEFT JOIN `ps_product_attribute` pa ON (p.`id_product` = pa.`id_product` AND default_on = 1)LEFT JOIN `ps_category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = 1) LEFT JOIN `ps_product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = 1) JOIN `ps_image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1) JOIN `ps_image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = 1) LEFT JOIN `ps_tax` t ON t.`id_tax` = p.`id_tax` LEFT JOIN `ps_tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = 1) LEFT JOIN `ps_manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` WHERE cp.`id_category` = 1 AND p.`active` = 1 ORDER BY cp.`position` DESC LIMIT 0,10 

解决方案 »

  1.   

    不慢才怪呢,你最好重新设计数据库。保持适当的冗余设计可减少sql复杂度。
      

  2.   

    谢谢各位,数据库早已定型,其他的查询都没问题,就是到这个速度非常慢.所以想看看有没有可能把这个SQL优化一下.
      

  3.   

    如果连接的列上都有索引,应该还好吧(p.`id_product` = pl.`id_product` AND pl.`id_lang` = 1) 
    这样的连接条件,我一般把后一个写在where里(因为只和pl相关),你试试
      

  4.   

    你可以用 EXPLAIN 来检查哪里有优化的可能
    你可以在 phpmyadmin 中执行
    EXPLAIN 你的SQL指令如果看不懂结果,就贴上来
      

  5.   

    谢谢各位,请看,这是EXPLAIN 的结果,请指教
      

  6.   

    图篇没有显示完全,这个是图片地址
    http://hi.csdn.net/attachment/201009/15/80532_1284513162XlW3.jpg
      

  7.   

    你主要where 的字段都加上索引
    或者JOIN on的字段加上
    在唯一性到字段也加上
      

  8.   

    首先要解决的是两个 type 为 ALL 的表。尤其是别名为 i 的表
    其次要解决的是 Excra 含有:
    Using temporary MYSQL需要创建一个临时表来存储结果
    Using filesort MYSQL需要进行额外的步骤来发现如何对返回的行排序
      

  9.   

    晕倒和我遇到的问题一样...我的语句好像是有修改过的.
    SELECT p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`,
    i.`id_image`, il.`legend`, t.`rate`, m.`name` AS manufacturer_name
    FROM `ps_product` p
    LEFT JOIN `ps_product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = 1)
    LEFT JOIN `ps_image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
    LEFT JOIN `ps_image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = 1)
    LEFT JOIN `ps_tax` t ON (t.`id_tax` = p.`id_tax`)
    LEFT JOIN `ps_manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
    LEFT JOIN `ps_category_product` cp ON (cp.`id_product` = p.`id_product`)
    INNER JOIN `ps_category_group` ctg ON (ctg.`id_category` = cp.`id_category`)
    INNER JOIN `ps_customer_group` cg ON (cg.`id_group` = ctg.`id_group`)
    WHERE p.`active` = 1
    AND DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL 300 DAY)) > 0
    AND (cg.`id_customer` = 0 OR ctg.`id_group` = 1)
    GROUP BY p.`id_product`
    ORDER BY p.`date_add` DESC
    LIMIT 0, 5
      

  10.   

    看了下 里面的条件都是有主键或者索引的...
    EXPLAIN 结果如下 请高人指点下呀~~图片地址 http://hi.csdn.net/attachment/201009/16/1819761_128463997814bF.jpg