2011-09-06 84 views
1

我們有一個XML列支持相當多的數據的表,這在我們的開發環境中工作正常,但隨着表增長(接近10,000行),我們開始看到性能的問題。SQL Server 2008 XML列性能問題

只是做SELECT *需要單獨12秒...

任何建議,以解決這個問題?

在此先感謝。

+0

您是否在桌面上有必要的索引?我懷疑數據行大小太大,只需要很多時間來返回數據... –

+0

你是如何做'SELECT *'? –

回答

1

你可以檢查出幾件事情 - 至少是對性能的影響主要是與處理,並從XML列中選擇數據時:

  • 你可以把一個index on your XML column - 這可以幫助,如果您需要從XML列中獲取大量數據。值得注意的一點是:XML索引使用很多磁盤空間的 - 在我們的例子中,1.5GB的數據庫飆升到11GB的磁盤大小....謹慎使用!

  • 您可以將XML中的某些元素「表面化」到「父」表上作爲計算的持久列,從而更快速地找到所需的行(需要存儲的函數 - 但是,如果它是一種非常好的技術,你有這方面的需求)

另外:永遠做一個SELECT *無論如何 - 如果你不需要XML列 - 不選擇它 - 這將是非常詳細,並使用相當多的內存。

0

只是添加了一些什麼marc_s說:我也會推薦一個索引 - 10K記錄不是很多。但請確保您正確地添加索引 - 通常放置索引的最佳位置是用於JOIN條件,WHERE子句或ORDER BY子句的列。如果您的查詢在這些情況下沒有使用XML本身,則可以通過在不同列上創建索引來更好地服務您(例如,如果您正在查找非XML列中的ID,則可能會看到通過在ID上創建索引來獲得更多益處)。

如果實際提取XML數據的速度很慢,您可以考慮製作一個覆蓋索引(使用INCLUDE關鍵字),其中您有一個ID索引,但INCLUDE表達式從XML列提取值。這對我的一個項目產生了巨大的影響,但是一如既往地確保測試性能。

當然,如果您的查詢實際上在對XML數據執行JOIN/WHERE/ORDER BY,那麼您應該可以執行marc_s建議並在XML列上創建索引。

+0

感謝這兩個回覆,這給了我一些想法,我們需要改進我們的應用程序。然而,目前我們的場景並不複雜,現在我們並沒有在SQL中對XML進行太多查詢,這個問題的用例是我們將整列和應用程序代碼轉換爲一個對象,其餘部分應用程序可以使用它,但是,一次只需拉動幾千個這些需要時間。有了這個說法,並且假設我們拉整列,索引仍然會有幫助嗎? – AVP06

+0

如果我們只取出部分XML節點而不是整列,它也會有什麼區別嗎? – AVP06

+0

通常,從數據庫傳輸到客戶端的數據越少,性能就越好。這就是爲什麼你應該避免「SELECT *」,而是隻選擇必要的列。同樣,如果您可以減少返回的行數(通過篩選記錄),這也會提高性能。如果索引對您的過濾有用,那麼索引會加快速度。是的,拉動XML的一個子集也可能會有所幫助。很難說沒有測試。 – JohnD

0

如果查詢記錄並過濾XML數據類型中的數據,則要求SQL Server檢查所有XML內容以查找結果。

要加快速度,請將XML數據類型過濾器與全文搜索表達式結合使用。在對XML進行分析和搜索之前,全文搜索會縮小搜索結果(取決於您的具體情況)。它可以節省大量的CPU和IO。這裏有一個例子:

SELECT * 
FROM Table 
WHERE CONTAINS(XmlColumn,'value') 
AND XmlColumn.exist('/element/element/text()[contains(.,"value")]') = 1 

這是微軟here記錄,並且您可以前後用統計運行你的查詢檢查。以下是關於如何打開統計信息的方法:

SET STATISTICS IO ON; 
SET STATISTICS TIME ON;