Mysqli加入查询非常慢

时间:2014-01-19 15:19:38

标签: mysql performance subquery left-join

我的网站有嵌套查询存储结果,最后在我的代码变大时给我带来问题。我正在尝试学习如何连接表和子查询,以便我可以简化我的代码。此查询返回我需要的确切信息,但添加此查询后,我的页面加载时间从1秒增加到9秒。有没有办法加快速度,或者是否有一些我在其中缺少的东西需要这么长时间?

SELECT p.product_id, 
       p.product_name, 
       p.product_pic, 
       AVG(r.review_stars), 
       COUNT(DISTINCT r.review_id), 
       (SELECT c.price_price FROM prices as c WHERE c.price_product=p.product_id ORDER BY c.price_price ASC LIMIT 1), 
       (SELECT c.price_vendor FROM prices as c WHERE c.price_product=p.product_id ORDER BY c.price_price ASC LIMIT 1) as VID, 
       p.product_url, 
       p.product_clicks, 
       SUM(c.price_clicks), 
       COUNT(c.price_price), 
       c.price_affiliate, 
       (SELECT v.vendor_name FROM vendors as v WHERE v.vendor_id=VID LIMIT 1) 
FROM products as p 
LEFT OUTER JOIN reviews as r ON p.product_id = r.review_product
LEFT OUTER JOIN prices as c ON c.price_product = p.product_id
GROUP BY p.product_id
ORDER BY p.product_clicks DESC
LIMIT 21

2 个答案:

答案 0 :(得分:0)

您可以按以下方式重写查询以减少子查询的影响:

SELECT

main_results.*,

(SELECT c.price_price FROM prices as c WHERE c.price_product=main_results.product_id ORDER BY c.price_price ASC LIMIT 1),
(SELECT c.price_vendor FROM prices as c WHERE c.price_product=main_results.product_id ORDER BY c.price_price ASC LIMIT 1) as VID,
(SELECT v.vendor_name FROM vendors as v WHERE v.vendor_id=VID LIMIT 1)

FROM

(

    SELECT p.product_id, 
           p.product_name, 
           p.product_pic, 
           AVG(r.review_stars), 
           COUNT(DISTINCT r.review_id),                 
           p.product_url, 
           p.product_clicks, 
           SUM(c.price_clicks), 
           COUNT(c.price_price), 
           c.price_affiliate               
    FROM products as p 
    LEFT OUTER JOIN reviews as r ON p.product_id = r.review_product
    LEFT OUTER JOIN prices as c ON c.price_product = p.product_id
    GROUP BY p.product_id
    ORDER BY p.product_clicks DESC
    LIMIT 21

) AS main_results

答案 1 :(得分:0)

你可以让它比vidaica的代码更快。

产品需要INDEX(product_clicks,product_id);然后看看这是否能为您提供所需的ID:

SELECT product_id FROM products ORDER BY product_clicks DESC LIMIT 21;

替换此行:

FROM products as p

FROM(SELECT product_id FROM products ORDER BY product_clicks DESC LIMIT 21)as ids JOIN产品p ON p.product_id = ids.product_id

(可能需要进行一些调整,例如删除外部LIMIT。)

他的建议背后的原则是在执行子查询之前将数据减少到只有21行。我继续前进了一步,同时避免了JOIN,直到只有21个。此外,我选择的INDEX允许扫描在INDEX中完成,而不是到达表中以找到product_clicks。

请参阅EXPLAIN了解“使用索引”。