2010-11-10 32 views
3

我有一個包含XML數據類型列的表。現在的方法是使用XPath來查詢XML中的值。不幸的是,這種方法變得非常緩慢。使用XPath查詢XML列的T-SQL非常慢 - 如何改進或選擇?

該表有大約500,000行。它實際上是一個每天接收新數據的登臺表,因此在列上應用XML索引是不切實際的 - 每日INSERT操作需要數小時才能完成。沒有索引,大約在一分鐘內完成。

有沒有其他辦法可以更快地查詢這個XML數據?

+0

如果你需要某種持續性指標,也許XML是不是你的格式... – 2010-11-10 22:10:55

+0

不需要索引 - XML索引似乎是我找到的常見解決方案,所以我嘗試了它,但對我的情況來說這似乎不實際。不幸的是,我對XML格式沒有太多選擇。 – capsaicin 2010-11-10 22:33:26

+0

是否可以修改應用程序/提供新數據的任何東西?因爲MSSQL中的XML支持是一個可怕的錯誤,你應該在外面預處理這些數據。 – 2010-11-11 08:48:44

回答

0

我們有相同的情況和數量的數據,並在調整結束後有一個插入&更新觸發器將數據插入「數據倉庫表」中。這給出了一個較慢的插入,但對我們的用戶可行。

7

您需要定期查詢XML中的多少項目?一些??

我們選擇面臨着同樣的問題,解決的辦法是這樣的:

  • 創建一個存儲功能,在該功能需要一個XML參數作爲其輸入
  • ,提取您從XML需要的信息使用XQuery/XPath的
  • 創建計算你的桌子上引用了功能持續列

通過這種方式,我們提取了三種,四種最常用的信息項(在我們的例子中通常只是一個INT),並將它們作爲基表的列提供。由於它們是持久的,因此每次訪問時都不會重新計算它們 - 僅當XML內容發生更改時纔會重新計算它們;也因爲它們被持久化了,如果需要的話,你可以在它們上面放置一個常規的非聚集索引。

例子:

我們已經提取從XML一個BIT告訴我們一個給定的合同是否有一個VPN連接或不是一個函數:給定一個XML

CREATE FUNCTION dbo.GetVPNFlag(@Data XML) 
RETURNS BIT 
WITH SCHEMABINDING 
AS BEGIN 
    DECLARE @VPNFlag BIT 

    SELECT 
    @VPNFlag = ISNULL(@Data.value('(EntryIP/VPNOption)[1]', 'bit'), 0) 

    RETURN @VPNFlag 
END 

,這將挑選出VPN標誌並返回。接下來,我們創建了我們的基表中的計算列仍然存在:

ALTER TABLE dbo.ContractData 
    ADD IsVPN AS dbo.GetVPNFlag(XmlData) PERSISTED 

在這裏,我們在XmlData內容正在傳遞從ContractData表,到函數。我們回來一個BIT,在ContractData表中存儲爲IsVPN列。

現在我們可以很容易地得到所有的合同與VPN這樣的:

SELECT (list of fields) 
FROM dbo.ContractData 
WHERE IsVPN = 1