簡體   English   中英

通過查詢優化聯接訂單

[英]Optimize joined order by query

我有以下查詢:

SELECT `p_products`.`id`, `p_products`.`name`, `p_products`.`date`, 
       `p_products`.`img`, `p_products`.`safe_name`, `p_products`.`sku`, 
       `p_products`.`productstatusid`, `op`.`quantity`
FROM `p_products` 
INNER JOIN `p_product_p_category` 
        ON `p_products`.`id` = `p_product_p_category`.`p_product_id`
LEFT JOIN (SELECT `p_product_id`,`order_date`,SUM(`product_quantity`) as quantity 
           FROM `p_orderedproducts` 
           WHERE `order_date`>='2013-03-01 16:51:17' 
           GROUP BY `p_product_id`) AS op
       ON `p_products`.`id` = `op`.`p_product_id`
WHERE `p_product_p_category`.`p_category_id` IN ('15','23','32') 
  AND `p_products`.`active` = '1'
GROUP BY `p_products`.`id`
ORDER BY `date` DESC

說說:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY p_product_p_category    ref p_product_id,p_category_id,p_product_id_2   p_category_id   4   const   8239    Using temporary; Using filesort
1   PRIMARY p_products  eq_ref  PRIMARY PRIMARY 4   pdev.p_product_p_category.p_product_id  1   Using where
1   PRIMARY   ALL NULL    NULL    NULL    NULL    78  
2   DERIVED p_orderedproducts   index   order_date  p_product_id    4   NULL    201 Using where

我在許多列上都有索引,包括p_products.date。

問題是當許多類別中有超過5000種產品時的速度。 60000產品需要> 1秒。 有什么方法可以加快速度嗎?

如果我刪除左連接也是如此,在這種情況下結果是:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  p_product_p_category    index   p_product_id,p_category_id,p_product_id_2   p_product_id_2  8   NULL    91167   Using where; Using index; Using temporary; Using filesort
1   SIMPLE  p_products  eq_ref  PRIMARY PRIMARY 4   pdev.p_product_p_category.p_product_id  1   Using where

中間表p_product_p_category在p_product_id和p_category_id上都有索引,以及兩者的組合索引。

試圖Ochi的建議,結果是:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY   ALL NULL    NULL    NULL    NULL    62087   Using temporary; Using filesort
1   PRIMARY nr1media_products   eq_ref  PRIMARY PRIMARY 4   cats.nr1media_product_id    1 Using where
2   DERIVED nr1media_product_nr1media_category  range   nr1media_category_id    nr1media_category_id    4   NULL    62066   Using where

我想我可以簡化問題,如何在類別中間表上加入我的產品,以獲取所選類別的所有獨特產品,按日期排序。

編輯:

這為我提供了類別中的所有獨特產品,而無需使用臨時表進行訂購或分組:

SELECT
    `p_products`.`id`,
    `p_products`.`name`,
    `p_products`.`img`,
    `p_products`.`safe_name`,
    `p_products`.`sku`,
    `p_products`.`productstatusid`
FROM
    p_products
WHERE
    EXISTS (
        SELECT
            1
        FROM
            p_product_p_category
        WHERE
            p_product_p_category.p_product_id = p_products.id
        AND p_category_id IN ('15', '23', '32')
    )
AND p_products.active = 1
ORDER BY
    `date` DESC

上面的查詢非常快,比使用group by(0.04 VS 0.7 sec)的連接快得多,雖然我不明白為什么它可以在沒有臨時表的情況下執行此查詢。

我想我需要為orderedproducts join找到另一個解決方案,它仍然會將查詢速度降低到> 1秒。 可能會讓cron每晚更新一次銷售產品的排名,並將該信息保存到p_products表中。

除非有人有明確的解決方案......

您將每種類型的類別加入到產品中 - 只有它才會按類別ID進行過濾

嘗試盡快限制您的查詢,例如,而不是

INNER JOIN `p_product_p_category`

INNER JOIN ( SELECT * FROM `p_product_p_category` WHERE `p_category_id` IN ('15','23','32') )

這樣你就可以從開始就開始研究較小的產品子集了

一種可能的解決方案是刪除派生表並只執行一個Group By:

Select P.id, P.name, P.date
    , P.img, P.safe_name, P.sku
    , P.productstatusid
    , Sum( OP.product_quantity ) As quantity
From p_products As P
    Join p_product_p_category As CAT
        On p_products.id = CAT.p_product_id

    Left Join p_orderedproducts As OP
        On OP.p_product_id = P.id
            And OP.order_date >= '2013-03-01 16:51:17' 

Where CAT.p_category_id In ('15','23','32') 
    And P.active = '1'
Group By P.id, P.name, P.date
    , P.img, P.safe_name, P.sku
    , P.productstatusid
Order By P.date Desc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM