2012-01-19 57 views
5

我有要求在我的SQL Server數據庫中搜索幾個不同的表。我需要根據在哪個表中匹配的結果對結果進行排序。優化跨多個表的全文搜索

我採取的方法如下所示。但是,隨着數據量的增長,這看起來效率不高。

任何人都可以建議任何技巧來優化?

-- Full-text query 
DECLARE @FtsQuery nvarchar(100) 
SET @FtsQuery = 'FORMSOF(INFLECTIONAL, detail)' 

-- Maximum characters in description column 
DECLARE @MaxDescription int 
SET @MaxDescription = 250 

SELECT 1 AS RankGroup, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) AS Description FROM Table1 
    INNER JOIN CONTAINSTABLE(Table1, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table1.Id 
UNION SELECT 2, FTS.Rank, Id, Title, NULL FROM Table2 
    INNER JOIN CONTAINSTABLE(Table2, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table2.Id 
UNION SELECT 3, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table3 
    INNER JOIN CONTAINSTABLE(Table3, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table3.Id 
UNION SELECT 4, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table4 
    INNER JOIN CONTAINSTABLE(Table4, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table4.Id 
UNION SELECT 5, FTS.Rank, Id, Title, LEFT([Description], @MaxDescription) FROM Table5 
    INNER JOIN CONTAINSTABLE(Table5, *, @FtsQuery) AS FTS ON FTS.[KEY] = Table5.Id 
ORDER BY RankGroup, Rank DESC 

我想過的一個想法是創建一個索引視圖,然後在視圖上執行搜索。但是由於這種觀點需要這些,所以很難看出這將更加有效。

+0

你可以安全地做一個簡單的優化是用'UNION ALL'替換'UNION'。欲瞭解更多信息:http://stackoverflow.com/questions/49925/what-is-the-difference-between-union-and-union-all – niaher

回答

7

這是一個難題,因爲CONTAINSTABLE一次只能搜索單個表的FTS索引。只要您的表現可以接受,您的UNION解決方案就沒有問題。

我們面臨同樣的問題,需要在單個查詢中從多個表中有效搜索多個列。我們所做的是將這些列和表中的所有數據彙總到一個只讀表中。然後,我們的查詢只需要一個電話CONTAINSTABLE

CONTAINSTABLE(AggregatedTable, AggregatedColumn, @FtsQuery) 

我們有運行每5-10分鐘,並逐步聚合來自我們的源表中的任何修改的內容爲我們的單隻讀聚合內容表中的計劃作業。

一般來說,在任何合理大小的數據庫和用戶負載中使用FTS似乎意味着您始終與性能作鬥爭。如果您發現不管您做什麼,都無法讓您的表現被接受,您可能需要調查其他技術,例如 Lucene

+0

有趣。你採取什麼類型的方法來獲取更改後的數據並將其推送到聚合表中?這個計劃的工作通常需要多長時間才能運行? – mg1075

+1

我們使用sql代理調度的存儲過程來更新非規格化表。我們的基礎數據在每行上都有一個日期時間標記,指示該行最後一次觸摸(插入或更新)的時間,因此我們使用它來每5或10分鐘執行一次增量填充。我們的初始負載需要一個小時左右,但增量人羣只需要10或20秒。 –

+0

感謝您的輸入。我認爲唯一值得關注的問題是:(1)查詢表以確定符合更新條件的記錄所需的時間,以及(2)是否存在任何通常會運行的停機時間和更新,目前只有一段記錄 - 沒有運行。 – mg1075