2016-11-25 44 views
0

我正在執行電子商務腳本。MySql優化僅用於從另一個表的列中選擇具有最大值的行

我有一個表「commerce_product」。

+--------------+---------+----------------------------+ 
| product_id | title | content     | 
+--------------+---------+----------------------------+ 
| 1   | ...  | ...      | 
| 2   | ...  | ...      | 
| 3   | ...  | ...      | 
| 4   | ...  | ...      | 
+--------------+---------+----------------------------+ 

我有一個表 「commerce_product_price_index」。在這張表中,我保存了每種產品的所有不同價格。 價格取決於customer_group,貨幣,國家,地理區域,客戶和日期。

這裏是這張表的一個例子。

+------+--------------+--------------------+--------------+-------------+-------------+----------+-------------+--------------+--------------+-------------+------------------+------------------+ 
| id | product_id | customer_group_id | currency_id | country_id | geozone_id | user_id | time_from | time_to  | min_price | max_price | final_min_price | final_max_price | 
+------+--------------+--------------------+--------------+-------------+-------------+----------+-------------+--------------+--------------+-------------+------------------+------------------+ 
| 1 | 1   | 0     | 0   | 0   | 0   | 0  | 1479942000 | 1480460400 | 500   | 500   | 300    | 300    | 
| 2 | 1   | 1     | 0   | 0   | 0   | 0  | 1479942000 | 1480460400 | 500   | 500   | 250    | 250    | 
| 3 | 1   | 2     | 0   | 0   | 0   | 0  | 1479942000 | 1480460400 | 500   | 500   | 200    | 200    | 
| 4 | 1   | 3     | 0   | 0   | 0   | 0  | 1479942000 | 1480460400 | 500   | 500   | 100    | 100    | 
+------+--------------+--------------------+--------------+-------------+-------------+----------+-------------+--------------+--------------+-------------+------------------+------------------+ 

在這個例子中,我有4分型動物產品的價格。

首先我做一個選擇來計算每個價格的分數。

SELECT 
    IF (1480090146 >= `time_from` AND 1480090146 <= `time_to`, 1, 0) + 
    IF (`customer_group_id` = 3, 2, 0) + 
    IF (`geozone_id` = 2, 4, 0) + 
    IF (`country_id` = 73, 8, 0) + 
    IF (`currency_id` = 1, 16, 0)+ 
    IF (`user_id` = 2352, 32, 0) AS score, 
    `cppi`.* 
    FROM 
     `commerce_product_price_index_2` AS `cppi` 
    WHERE 
     (geozone_id IN('2', 0)) 
     AND (country_id IN('73', 0)) 
     AND (currency_id IN('1', 0)) 
     AND (customer_group_id IN('3', 0)) 
     AND (user_id IN('2352', 0)) 
     AND (cppi.time_from <= 1480090146) 
     AND (cppi.time_to >= 1480090146) 
    ORDER BY `score` desc 

我有一個2個結果與新列得分

+--------+------+--------------+--------------------+--------------+-------------+-------------+----------+-------------+--------------+--------------+-------------+------------------+------------------+ 
| score | id | product_id | customer_group_id | currency_id | country_id | geozone_id | user_id | time_from | time_to  | min_price | max_price | final_min_price | final_max_price | 
+--------+------+--------------+--------------------+--------------+-------------+-------------+----------+-------------+--------------+--------------+-------------+------------------+------------------+ 
| 3  | 1 | 1   | 0     | 0   | 0   | 0   | 0  | 1479942000 | 1480460400 | 500   | 500   | 300    | 300    | 
| 1  | 2 | 1   | 1     | 0   | 0   | 0   | 0  | 1479942000 | 1480460400 | 500   | 500   | 250    | 250    | 
+--------+------+--------------+--------------------+--------------+-------------+-------------+----------+-------------+--------------+--------------+-------------+------------------+------------------+ 

而在這個結果我選擇了最高分拿到好價錢。

SELECT 
    `cppi2`.*, 
    MAX(score) 
FROM (
    SELECT 
     `cppi`.*, 
     IF (1480090146 >= `time_from` AND 1480090146 <= `time_to`, 1, 0) + 
     IF (`customer_group_id` = 3, 2, 0) + 
     IF (`geozone_id` = 2, 4, 0) + 
     IF (`country_id` = 73, 8, 0) + 
     IF (`currency_id` = 1, 16, 0)+ 
     IF (`user_id` = 2352, 32, 0) AS score 
     FROM 
      `commerce_product_price_index` AS `cppi` 
     WHERE 
      (geozone_id IN('2', 0)) 
      AND (country_id IN('73', 0)) 
      AND (currency_id IN('1', 0)) 
      AND (customer_group_id IN('3', 0)) 
      AND (user_id IN('2352', 0)) 
      AND (cppi.time_from <= 1480090146) 
      AND (cppi.time_to >= 1480090146) 
     ORDER BY `score` desc 

    ) AS `cppi2` 
GROUP BY `product_id` 

而我選擇我的產品表後,我做了一個加入這個請求。

我的問題是:這是做這件事的好方法嗎?

我的產品表有13000行。 我的價格指數表有50000行。

你有最好的解決方案嗎?

+0

請參閱http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple- sql-query – Strawberry

回答

0

看起來你可以從得分計算中刪除time_fromtime_to部分,因爲這是WHERE子句的一部分。

有沒有必要ORDER BY score - MAX(score)將照顧。

您應該考慮選擇只列需要,而不是SELECT cppi.*

您的解決方案似乎是合理的我。其他解決方案包括計算代碼中的分數(或者只是使用if/else/case語句來依次檢查user_id,customer_group_id等),而不是使用mysql。

我試圖想出一個解決方案,使用計算的布爾標誌來判斷屬性是否匹配,然後按順序排列,但我無法使它與GROUP BY product_id一起使用。那裏可能有解決方案,但我認爲它不會更快。

+0

您可以發表評論。 我不知道是否最好創建一個臨時表? – anardil

相關問題