2011-01-26 44 views
15

我有一個SQL查詢,我將在多個存儲過程中重複使用。該查詢針對多個表起作用,並基於傳遞給它的2個變量返回一個整數值。重用SQL與視圖或功能

而不是在不同的存儲過程重複查詢我想分享它,並有2種選擇:

  1. 創建一個視圖,我可以加入到基於變量,並從它那裏得到的整數值。
  2. 與傳遞給它的標準再創建一個函數,返回整型變量

我傾向於選擇1,但想去就這是更好的和普遍的做法。這將是更好的性能明智等(加入到一個視圖或調用函數)

編輯:RDBMS是SQL Server的

回答

13

如果你總是使用相同的參數化謂詞來過濾結果,那麼我會去參數化的內聯表值函數。從理論上講,這被視爲與View相同,因爲它們在實踐中被優化器擴展出來,可以避免謂詞推動問題。這種情況的一個例子可以在this article的第二部分看到。

正如Andomar在大多數時候的評論中指出的那樣,查詢優化器在將謂詞推送到需要的位置時確實做得很好,但我不知道使用內聯TVF將執行的任何情況更糟的是,這似乎是兩個(非常相似)結構之間的理性默認選擇。

我可以看到的一個優點是,它可以讓你選擇沒有過濾器或不同的過濾器,因此更通用。

爲了提高效率as in this example,內聯TVF也可用於替換標量UDF。

1

你不能傳遞變量到視圖,這樣看來你唯一的選擇是使用功能。有兩種可選方式:

  • 標量函數
  • 表值函數(內聯或多語句)

如果你正在返回的記錄,那麼你可以使用WHERE子句從外面看一個不太複雜的VIEW,它可以在視圖內嵌入到查詢中,但是因爲所有返回的是一列integer value,所以視圖將不起作用。

查詢優化器可以擴展內聯TVF以與外部(調用)查詢一起工作,所以與SCALAR函數相比,它在大多數情況下可以更快。

然而,慣例是不同的 - 一個標量函數返回一個值立即

select dbo.scalarme(col1, col2), other from .. 

而直列TVF需要你要麼子查詢,或CROSS APPLY對另一臺

select (select value from dbo.tvf(col1, col2)), other from .. 

-- or 

select f.value, t.other 
from tbl t 
CROSS apply dbo.tvf(col1, col2) f -- or outer apply 
+0

視圖可以返回單列單行結果。誠然,這不是一種常見的情況,但仍可能比標量UDF更高效。編輯 - 啊你正在質疑參數化方面。我認爲這將通過視圖上的謂詞。 – 2011-01-26 23:35:44

0

我打算給你一個半答案,因爲我不確定在表現上哪些更好,我很抱歉。但是,那麼其他人肯定會得到很好的建議,我敢肯定。

我會堅持你的'普遍實踐'問題的一部分。

所以,在這種情況下,標量函數在我看來似乎是一個自然的解決方案。爲什麼,你只需要一個值,一個整數值被返回 - 這是標量函數的目的,不是嗎?但是,如果我能夠看到後面我需要多個值的概率,那麼我可能會考慮切換到TVF。那麼,如果你已經實現了你的標量函數並在你的應用程序的許多地方使用它,現在你需要使用基本相同的邏輯來返回一行,一列或一列值的數據呢?

在我看來(沒有雙關語意圖),視圖可能會變成類似標量和表值函數的最大公約數。這些功能只需要應用參數。

現在你已經說過你只打算選擇使用哪個選項。然而,考慮到上述情況,我仍然認爲視圖可以是一個很好的選擇,並且在擴展應用程序時證明是有用的,並且您可以實際使用視圖和函數(如果這樣做不會使性能太糟糕)就像我一樣描述。

0

一個TVF擁有的觀點的一個優點是你可以強制誰調用它來定位一個特定的索引。