[英]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.