2014-03-06 126 views
1

我在我的MySQL數據庫中有一個存儲過程,工作正常。Mysql在查詢中多次使用存儲過程結果

但是,由於我必須在相同的查詢中使用相同的參數調用相同的過程3次,如果我可以使用第一次調用的結果而不是後續調用,那麼它會是一個很好的性能改進。

編輯:改變的例子,因爲它過於簡單化,誤導性答覆

我要表:產品,價格 - 價格取決於一年的時間而改變,付款方式,因此結構:(ID,PRODUCT_ID,date_from,DATE_TO,price_mode_1,price_mode_2,price_mode_3)

例子:

我現在要做的就是

SELECT products.*, 
     get_a_quote(products.id,date_to,date_from, quantity_mode_1,quantity_mode_2,quantity_mode_3) 
    FROM peoducts 
WHERE get_a_quote(products.id,date_to,date_from, quantity_mode_1,quantity_mode_2,quantity_mode_3) >0 
ORDER BY 
     get_a_quote(products.id,date_to,date_from, quantity_mode_1,quantity_mode_2,quantity_mode_3) 
LIMIT 10 

我想做的事是

SELECT products.*, 
     get_a_quote(products.id,date_to,date_from, quantity_mode_1,quantity_mode_2,quantity_mode_3) into quote 
    FROM peoducts 
WHERE quote >0 
ORDER BY 
     quote 
LIMIT 10 

這可能嗎?

* 編輯:功能代碼*

FUNCTION `get_a_quote`(`productid` INT, `startDate` SMALLINT, `endDate` SMALLINT, `mode_1_quantity` SMALLINT, `mode_2_quantity` TINYINT, `mode_3_quantity` TINYINT) RETURNS smallint(6) 
BEGIN 
declare totalprice,p_1,p_2,p_3 smallint; 
SELECT price_1,price_2,price_3 into p_1,p_2,p_3 FROM pricing WHERE id=productid and ((startDate between date_from and date_to) and (endDate between date_from and date_to)); 
if p_3 is null then 
    set mode_2_quantity=mode_3_quantity+mode_2_quantity; 
    set mode_1_quantity=mode_1_quantity+(4*mode_3_quantity); 
    set p_3=0; 
    set mode_3_quantity=0; 
end if; 
if p_2 is null then 
    set mode_1_quantity=mode_1_quantity+(3*mode_2_quantity); 
    set p_2=0; 
    set mode_2_quantity=0; 
end if; 
if mode_1_quantity>0 and p_1 is null then 
    return 0; 
end if; 
set totalprice = p_1*mode_1_quantity+p_2*mode_2_quantity)+p_3*mode_3_quantity); 
RETURN totalprice; 
END 

謝謝大家

+0

[學習變量](http://dev.mysql.com/doc/refman/5.0/en/user-variables.html) – Alexander

+0

你可以把整個SP代碼?值是否是您想要存儲在變量中的值? –

+1

你在說的是功能,而不是程序。不同的故事...... – fancyPants

回答

1

您可以在派生表做到這一點:

SELECT * 
FROM (
    SELECT customers.*, 
      totalOrders (customers.id) AS total 
     FROM customers 
) AS t 
WHERE total >0 
ORDER BY 
     total 
LIMIT 10 

不過,我不會使用存儲功能這一點。它肯定會有令人難以置信的糟糕表現。

我會使用一個JOIN,這樣我只能獲取零個訂單以上的客戶。

+0

它必須是一個函數,它不只是一個像名字會建議的總和,但也有一些IFs和一些更多的數學。那麼,你認爲這個派生表會比我現在使用的3個函數調用性能提升嗎? – Dariomarciano

+0

已經使用php的microtime進行了一段時間的測試,您的解決方案比我的效率高出30%左右。非常感謝! – Dariomarciano

0

對我來說,語義上看起來要添加在桌子上一個新的,依賴列。對於您可以使用一個觀點:

CREATE VIEW v AS 
SELECT customers.*, 
    get_a_quote(products.id,date_to,date_from, quantity_mode_1,quantity_mode_2,quantity_mode_3) AS total 
FROM customers; 

然後,你可以簡單地使用它在您的查詢:

SELECT * 
FROM v 
WHERE total >0 
ORDER BY 
    total 
LIMIT 10; 

不過話又說回來你的函數是做可能會使用你的表一個JOIN得到更好的實現,像這樣:

SELECT customers.*, 
     SUM(orders.value) 
FROM 
    customers 
    JOIN orders ON 
     customers.id=orders.customer_id 
GROUP BY customers.id 
HAVING SUM(orders.value) >0 
ORDER BY 
    SUM(orders.value) 
LIMIT 10; 

你能告訴我們你的功能代碼嗎?

+0

發佈了更多信息,我不認爲它可以用視圖來完成,因爲函數結果因請求而異,它不是一個簡單的總數。 – Dariomarciano

+0

我完全不明白爲什麼不能用視圖來完成:你可以嘗試運行我的視圖定義和使用視圖的以下查詢,並告訴我們你得到了什麼錯誤信息? –

+0

這不是我得到一個錯誤,只是這樣我每次用戶想要一個報價時都必須創建一個不同的視圖,選擇它,然後當他想要一個不同的報價時放下它。這似乎比我現在正在做的3個函數調用效率更低,我錯了嗎? – Dariomarciano

相關問題