2010-05-28 43 views
4

我有一個查詢與約6-7連接表並在其中基表的6列的FREETEXT()謂詞。現在SQL Server 2005中FREETEXT()性能比較問題

,這個查詢過去一年工作的罰款(下2秒)和幾乎保持不變(我試圖舊版本和問題依然存在)

所以今天,突然,同樣的查詢時間大約1-1.5分鐘。

在SQL Server 2005中檢查執行計劃,重建該表的FULLTEXT索引,重新組織FULLTEXT索引,從頭創建索引,重新啓動SQL Server服務,重新啓動整個服務器之後,我不知道還有什麼嘗試。

我暫時切換查詢中使用LIKE代替直到我算出這個(這需要大約6秒現在)。

當我查看查詢性能分析器中的查詢時,當我將'FREETEXT'查詢與'LIKE'查詢進行比較時,前者具有350倍的讀取次數(4921261比13943)和20次(38937與1938年相比)後者的CPU使用率。

所以這真的是導致它這麼慢的'FREETEXT'predicate。

有沒有人有什麼原因可能是什麼想法?或者我可以做更多的測試?

[編輯]

好吧,我剛剛運行的查詢再次得到執行計劃,現在再次需要2-5秒,沒有給它所做的任何更改,但這個問題昨天依然存在。這不是由於任何外部因素造成的,因爲我在上個星期四第一次測試該問題時停止了所有訪問數據庫的應用程序,所以這不是由於任何其他負載所致。

好吧,我還是會包括執行計劃,儘管它可能不會有很大的幫助,現在一切都工作了...請注意,這是一個巨大的查詢,我不能改變舊的數據庫(即數據標準化或擺脫一些不必要的中間表)

Query plan

確定這裏是完整的query

我可能要解釋正是它。基本上它獲得了招聘廣告的搜索結果,其中有兩種類型的廣告,優質廣告和普通廣告。結果分頁到每頁25個結果,10個頂級頂級和15個普通的結果,如果有足夠的話。

因此,有兩個內部查詢根據需要選擇許多高級/普通查詢(例如,在第10頁上,它會提取前100名高級數據和前150個普通數據),那麼這兩個查詢將與row_number()命令和一些數學。然後按rownumber排序組合並返回查詢。以及它在另一個地方用來獲取當前頁面所需的25個廣告。

哦,這個整個查詢是在一個巨大的遺留Coldfusion文件中構建的,因爲它一直在正常工作,所以我還沒敢達到/改變大部分......從來沒有碰過正在運行的系統等等)小東西像改變中央where子句的位。

該文件還生成其他基本相同的查詢,但沒有保費/非保費區分以及此查詢的很多其他變體,所以我從不確定對其中一個變更可能會發生何種變化其他...

好的,因爲問題沒有再出現,我給了馬丁賞金,因爲他迄今爲止最有幫助,我不希望賞金過期不必要的。由於每個人的努力,我會嘗試你的建議,如果它再次發生:)

+0

你可以發佈執行計劃嗎?問題可能與Martin建議的一致,在這種情況下,使用FORCE ORDER重新排序查詢可能會有所幫助。 – 2010-05-31 16:35:04

+0

奇怪。我假定您使用的是之前存在問題的相同FreeText搜索詞,並且數據中沒有任何變化(例如歸檔過程),可能突然導致來自FREETEXT部分的匹配記錄數量在一夜之間減少? – 2010-06-01 09:28:05

+0

此外,如果確實設法讓問題重現,您可以使用Management Studio中的「包括實際執行計劃」選項並將其另存爲* .sqlplan(XML格式)? – 2010-06-01 09:49:09

回答

1

可能出現此問題是由於將由全文查詢導致返回結果數量的差基數估計JOIN操作的策略很差。

如果您將其分爲兩個步驟,您會發現性能如何?

用於填充與全文查詢,第二個改變現有查詢引用臨時表,而不是結果的臨時表或表變量的一個新的臺階。 (注意:您可能想要嘗試加入或不加入OPTION(RECOMPILE),同時查看(A)返回許多結果的自由文本搜索項的查詢計劃(B)僅返回少數結果的查詢計劃。)

編輯這是很難在沒有違規查詢的確切澄清,但我的意思是不是做

SELECT <col-list> 
FROM --Some 6 table Join 
WHERE FREETEXT(...); 

這是如何執行?

DECLARE @Table TABLE 
(
<pk-col-list> 
) 
INSERT INTO @Table 
SELECT PK 
FROM YourTable 
WHERE FREETEXT(...) 

SELECT <col-list> 
FROM --Some 6 table Join including onto @Table 
OPTION(RECOMPILE) 
+0

你是什麼意思?'如果你把它分成兩步,你怎麼看待表現? ?在當前的情況下,這對我來說並不合理。 明天我會在工作中發佈執行計劃,但這是一個巨大的查詢(對兩個連接的子查詢和大量連接使用rownumber分頁),所以肯定會有很多可能的性能調優。但正如我所說,我想知道爲什麼在一個月前查詢最後一次更改(突然增加了where子句)時突然執行的時間大約延長了50倍,並且工作得很好,直到4天前... – Zenon 2010-05-31 18:45:31

+0

是的,需要查看查詢計劃才能對此進行猜測。 – 2010-05-31 19:11:17

+0

好吧,我試着用'DECLARE @ Table'和'OPTION(RECOMPILE)',它需要3秒,就像原來的查詢一樣。 但是當問題再次出現時,我將不得不測試它。 順便說一句,當我刪除約束條件以從查詢中只搜索活動(狀態= 3)行時,所以搜索所有行(大約一百萬)而不是19,000行,查詢仍然需要3秒鐘,所以我懷疑這是因爲一些數據庫條目在過去3天內已被設置爲非活動狀態。 – Zenon 2010-06-01 13:47:32

0

通常當我們遇到這個問題時,這是因爲表的碎片和陳舊的統計問題。

下一次,嘗試重建/重新索引後EXEC sp_updatestats

更多信息,請參見Using Statistics to Improve Query Performance

+0

是的,這也是一種可能性,儘管它不能解釋爲什麼它適用於運行相同統計的LIKE查詢。 – 2010-06-02 22:08:42

+0

FREETEXT和LIKE正在使用不同的統計信息,我相信(FEETEXT被視爲遠程源,與LIKE的實際索引統計信息)。 – GalacticJello 2010-06-03 15:53:18

+0

正確。 SQL2005中的FREETEXT沒有任何統計數據可用於進行任何基數估計,並且不會受到sp_updatestats的影響(總是假設1行將被返回),因此我的答案中的建議將其分開。因此,我所做的一點是,如果一個更依賴統計的查詢沒有遇到同樣的問題,那很奇怪(儘管可能)。 – 2010-06-05 08:48:41