2011-05-10 76 views
0

我正在使用一個應用程序,該應用程序在數據層中的整個WHERE子句中都有用戶函數,並且我確信它會導致性能問題。將函數轉換爲存儲過程

舉個例子,假設有一個報告,拉動條目和評論,並有一個功能

where (dbo.CountComments(entries.id, '5/10/2011') = 0) 

...我們展示,讓我們說,沒有評論今天的條目。

我想將其轉換爲存儲過程,但似乎幾乎不可能從存儲過程中獲得相同的行爲。

如果你不得不重寫這個SP,你會怎麼做?

回答

2

一些想法。

首先,使用COUNT = 0來找出沒有任何東西是低效的。你最好不要使用

NOT EXISTS (SELECT...) 

這樣SQL爲它找到一個行返回,而不必訪問他們都返回一個非零計數錯誤能夠儘快擺脫困境。

其次,你在哪裏查詢中使用這個函數?如果你不想像你的例子那樣使用它的輸出作爲查詢條件,那麼你就不能用存儲過程來做到這一點。

我發現自己正在爲通常使用的查詢編寫函數或視圖,然後在我想要返回它們返回的行時將其中一些包裝在存儲過程中。如果我必須將結果與其他表或視圖結合起來,最好將它們作爲函數。

+0

準確地說 - 我想使用它的輸出作爲查詢條件。感謝您提供這個逃避我的措辭。觀點也是一個好主意,謝謝。 – dnord 2011-05-10 19:32:40

0

你可以嘗試使用基本的SQL。可能類似於以下內容:

SELECT * 
FROM  comments c 
WHERE NOT EXISTS(SELECT commentID FROM comments c2 WHERE dateCreated >= getDate() AND c.commentID = c2.commentID) 

這比在幾個級別上使用函數更有效。但是我正在對你想要完成的事情做出一些基本的假設,所以我完全有可能離開這個標記。

+0

不,你在。不過,添加「NOT EXISTS」子句似乎比函數慢。不過,我會繼續玩這個主意。 – dnord 2011-05-10 19:39:04

+0

你碰巧知道你加入的列是否被編入索引?如果不是,那肯定會減慢速度。 – 2011-05-10 19:41:02

0

如果將其重寫爲存儲過程,則不能在WHERE子句中使用它。只有功能會給你這個能力。但是,如果你從函數中獲取代碼並將其放入存儲過程中,然後將參數中的日期作爲參數傳遞,那麼現在就可以獲得像現在這樣獲得的結果,除了使用存儲過程執行此操作。