2014-01-19 189 views
0

我的网站有嵌套查询存储结果,并最终给我的问题,因为我的代码变得更大。我正在尝试学习如何连接表并进行子查询,以便简化我的代码。此查询返回我需要的确切信息,但添加此查询后,我的页面加载时间从1秒变为9秒。有什么办法可以加快速度,还是有一些我错过的东西需要这么长时间?Mysqli加入查询非常缓慢

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 
+0

发布表结构 – Sara

+0

这很慢,因为您使用了大量依赖主查询的子查询。他们是3个子查询来获取prices.price_price,prices.price_vendor,vendors.vendor_name。您可以通过首先获取其他信息加快查询速度,然后将结果集与价格和供应商联系起来,以获取这些信息。 – vidaica

回答

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 
0

可以可能使它更快认为vidaica的代码。

产品将需要INDEX(product_clicks,product_id);然后看看这是否给你所需的ID:

SELECT product_id FROM products ORDER BY product_clicks DESC LIMIT 21;

的替换这一行:

FROM产品为p

FROM(SELECT PRODUCT_ID FROM产品ORDER BY product_clicks DESC LIMIT 21)如IDS JOIN产品P的p.product_id = ids.product_id

(有可能需要一些更多的调整,例如去掉了外LIMIT。)

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

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