2011-11-27 51 views
4

我有一個視圖從一個表中提取一些信息與XML數據。
每個文檔包含一個Product和幾個PurchaseOrderDetail。我想爲每個Product創建一個全部爲PurchaseOrderDetail的視圖。如何重寫SQL xpath查詢,以便能夠創建索引視圖

CREATE VIEW [dbo].[XML_PurchaseOrders] 
WITH SCHEMABINDING 
AS 
    SELECT 
    p.n.value('.', 'int') AS PurchaseOrderID 
    ,x.ProductID 
    FROM dbo.XmlLoadData x 
    CROSS APPLY x.PayLoad.nodes('declare namespace NS="http://schemas.datacontract.org/2004/07/XmlDbPerfTest"; 
    /NS:ProductAndRelated/NS:Product/NS:PurchaseOrderDetails/NS:PurchaseOrderDetail/NS:PurchaseOrderID') p(n) 
GO 

PayLoad列包含XML數據。

該視圖的問題在於,由於XML文檔既大又豐富,所以速度很慢。

我想指數這一觀點但給我的錯誤

不能創建視圖「XmlLoad.dbo.XML_PurchaseOrders」指標,因爲它包含一個適用。考慮不索引視圖,或刪除APPLY。

是否有可能重寫視圖使其能夠添加索引?

我已經嘗試了幾次嘗試,主要是與select ... from (select ....) innnerSelect group by foo,但都失敗了一個或另一個關於視圖索引的規則。

+0

因爲您需要使用XML中的多個節點,所以我沒有看到如果沒有'CROSS APPLY',我怎麼能做到這一點,因此我沒有看到如何在這樣的視圖中做到這一點,您可以創建一個索引視圖:-( –

+0

@marc_s,我也沒有,但我希望有一些其他方式來擴展我不知道的XML –

+0

我假設沒有選項可以從XML中提取這些數據並存儲在關係表中? – billinkc

回答

1
Is it possible to rewrite the view to make it possible to add an index? 

我不這麼認爲號。相反,我要使用this問題中的一些信息,並提出另一種方法。

您可以將計算的持久列添加到只保存具有該ID的XML的表中。不允許在計算列中直接使用XQUERY,但可以使用用戶定義的函數。

下面是函數:

create function dbo.GetPurchaseOrderID(@XMLData xml) 
returns xml with schemabinding 
as 
begin 
    return @XMLData.query('declare namespace NS="http://schemas.datacontract.org/2004/07/XmlDbPerfTest"; 
    /NS:ProductAndRelated/NS:Product/NS:PurchaseOrderDetails/NS:PurchaseOrderDetail/NS:PurchaseOrderID') 
end 

與持久化XML列創建該表:

CREATE TABLE [dbo].[XmlLoadData](
    [ProductID] [int] NOT NULL identity, 
    [PayLoad] [xml] NOT NULL, 
    [Size] AS (len(CONVERT([nvarchar](max),[PayLoad],0))), 
    [PurchaseOrderIDs] AS dbo.GetPurchaseOrderID(PayLoad) PERSISTED, 
CONSTRAINT [PK_XmlLoadData] PRIMARY KEY CLUSTERED 
(
    [ProductID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

查詢得到的ID:對我而言

;with xmlnamespaces('http://schemas.datacontract.org/2004/07/XmlDbPerfTest' as NS) 
select ProductID, 
     P.N.value('.', 'int') as PurchaseOrderID 
from XmlLoadData 
    cross apply PurchaseOrderIDs.nodes('NS:PurchaseOrderID') as P(N) 

有限的測試顯示它有點快。如果你的XML文檔很大,那應該是一個更大的改進。我懷疑它會將性能提高1000倍,因爲您仍然在處理解釋XML,但是您告訴我。沒有你的數據我當然沒有辦法測試。

+0

這聽起來很有趣。我想我可以使用一個函數來構建一個精簡版的XML,只需要我爲視圖所需的數據(在現實生活中,我有更多的數據而不是一個項目)。然後,我可以從最小的XML中創建我的視圖。 –

0
+0

XML索引不是一個選項。它至少爲數據庫大小增加了10GB,並且我們經常在網絡上處理數據庫副本。我只想索引XML數據中的一小部分內容。 XML文件很大,很多。 –

+0

我也嘗試了一個更小的數據子集上的XML索引,但改進只有2倍左右。我需要1000倍左右。 –