2009-11-07 22 views
0

我正在尋找在以下定位技術意見:嘗試使用表值函數

我們先從2個表:

tblProducts : ProductID, Name,Description,SomeAttribute 
tblProductsLocalization : ProductID,Language,Name,Description 

和表值函數:

CREATE FUNCTION [dbo].[LocalizedProducts](@locale nvarchar(50)) 
RETURNS TABLE 
AS (SELECT a.ProductID,COALESCE(b.Name,a.Name)as [Name],COALESCE(b.Description,a.Description)as [Description],a.SomeAttribute 
from tblProducts a 
left outer join tblProductsLocalization_Locale b 
on a.ProductID= b.ProductID and b.[Language][email protected]) 

我打算做的是包括功能每當我需要本地化的數據返回:

select * from LocalizedProducts('en-US') where ID=1 

代替

select * from tblProducts where ID=1 

我很感興趣,如果有重大的性能問題,以防萬一這個或任何攪局者。任何我不應該採用的理由?

編輯:我已經標記了這個SQL2005,儘管我用2008開發了這個,我認爲部署目標只有SQL2005。如果需要,我可以升級到2008年。

後來編輯:

我已經創建了一個視圖,相同的內容,但沒有參數:

CREATE VIEW [dbo].[LocalizedProductsView] 
AS 
SELECT b.Language,a.ProductID,COALESCE(b.Name,a.Name)as [Name], 
COALESCE(b.Description,a.Description)as [Description],a.SomeAttributefrom tblProducts a 
left outer join tblProductsLocalization_Locale b on a.ProductID= b.ProductID 

我然後繼續運行一些測試: 估計的執行計劃看起來與這兩個查詢:

select * from LocalizedProducts('us-US') where SomeNonIndexedParameter=2 

select * from LocalizedProductsView where (Language='us-US' or Language is null) and SomeNonIndexedPramaters=2 

最後一個問題,即arrises是:我應該理解TVF是否正在計算所有產品的翻譯,而不管WHERE參數如何?視圖是做同樣的事情嗎?

+0

SQL Server?你能否使用版本(2000 vs. 2005 vs. 2008)?在不同的SQL版本中,處理UDF的方式顯着不同。 – 2009-11-07 17:15:00

+0

@Radu:使用視圖而不是函數。您的功能是作爲SUBSELECT工作 - 不需要它,並且根據將來的使用情況,您可能需要其他相關信息。 – 2009-11-07 17:38:13

+0

據我瞭解,我無法將參數傳遞到視圖,我可以嗎? – Radu094 2009-11-07 17:41:20

回答

0

我想在做更多的測試之後回來回答這個問題。 這在我看來,SQL2008實際上是在尋找的TVF內執行查詢計劃時,並進行相應的優化:

例如:

select pr.* from LocalizedProducts('en-US') pr inner join LocalizedPhotos('en-US') ph on 
ph.ProductId=pr.Id where pr.SomeUnindexProperty= 5 

此查詢需要觸及4個表:

Products 
Products_Localization 
Photos 
Photos_Localization 

查詢計劃看起來的方式是(讓我看看我是否可以格式化):

Product gets a Clustered Index Seek 
     -- >> Products gets nested loop with Photos 
           -->> nested loop Products_Localization - 
              ->> nested loop Photos_Localization. 

如果TVF是一個黑匣子,這不是你所期望的。產品獲取索引SEEK這個簡單的事實會告訴我,查詢不會盲目地解釋整個TVF。

我運行了很多性能測試,平均而言,「本地化」TVF比使用直接表查詢要慢50%-100%,但這應該是TVF中涉及的表的兩倍比在正常的查詢。

0

這是一個安全的賭注,你將不得不翻譯產品名稱。所以我會設計翻譯解決方案來處理任何類型的字符串。

例如,你可以有一個定位表所示:

Id, TranslatableStringId, Language, Translation 

那麼,每個產品可以有與之相關聯的翻譯字符串。但也是產品列表頂部的說明文字。

對於產品,你會像查詢:

SELECT  * 
FROM  Products p 
INNER JOIN Translations t 
ON   p.DescriptionId = t.TranslatableStringId 
AND  t.language = 'en-US' 

的解釋性文字,你會得到一個簡單的:

SELECT  t.Translation 
FROM  Translations t 
WHERE  t.TranslatableStringId = 123 -- ID of string 
AND  t.language = 'en-US' 

附:對於一個真正的程序,我會使用比TranslatableStringId更簡短的描述,比如tsid,因爲翻譯往往隨處可見。

+0

請不要使用簡寫名稱作爲列名稱 - 沒有什麼比只有在有足夠多的字符支持可讀的,信息豐富的列名稱時找不到別名的速記更糟。特別是在ORM中,您不太可能參考完整的參考文獻。 – 2009-11-07 17:43:47

+0

你是否需要'TranslatableStringId'列 - 不會是'Id'列嗎?奇怪的是,'ID'看起來像PK,但你沒有引用它。我仍然將它命名爲更明顯的東西:'TRANSLATION_ID'或'LOCALIZATION_ID' ... – 2009-11-07 17:46:55

+0

一個'id'標識一種語言的字符串。一個'TranslatableStringId'標識同一個字符串的多個翻譯。 – Andomar 2009-11-07 17:52:15

1

簡短的回答:一般來說,沒有什麼錯用TVF對於這樣的事情,但我會建議把ID爲參數,也:

CREATE FUNCTION [dbo].[LocalizedProducts](@ID int, @locale nvarchar(50)) 
RETURNS TABLE 
AS (SELECT a.ProductID,COALESCE(b.Name,a.Name)as [Name],COALESCE(b.Description,a.Description)as [Description],a.SomeAttribute 
from tblProducts a 
left outer join tblProductsLocalization _Locale b 
on a.ProductID= b.ProductID and b.[Language][email protected]) 
where a.ProductId = @ID 

使用像這樣:

select * from LocalizedProducts(1, 'en-US') 

更詳細的解釋: 我從來沒有嘗試過在2008年SQL這樣的事情呢,所以它可能是SQL Server可以優化這個問題了。然而,我在早期版本中的經驗似乎表明,SQL Server傾向於以比聲明方式更程序化的方式處理用戶定義的函數,因此它不會解釋你想要的,然後找出最佳方式讓你得到你想要的東西,但實際上是按照你寫的指示執行。因此,在我看來,這種方法將:

  1. 選擇所有英文文本,將其放入一個表變量。
  2. 取得步驟#1的結果並選擇具有給定ID的任何記錄。

這意味着很多浪費的週期,在將ID過濾器應用到該結果集之前,將大部分未使用的英文文本放入表變量中。另一方面,將所有過濾器放入UDF將讓SQL Server確定是否最容易先通過ID進行過濾(更可能,假設採用標準索引方案),然後應用區域過濾器,反之亦然。無論哪種方式,如果您將所有過濾器放在同一個位置,則應該在背景中移動的數據量更少,從而獲得更好的性能。再次,這一切都假定SQL Server現在不在優化方面取得巨大飛躍。但是,如果是這樣,那更有理由說,是的,使用TVF沒有問題。

+0

這將如何表現產品列表? – Andomar 2009-11-07 17:34:59

相關問題