2012-04-08 19 views
1

次のように我々は構造を持つ当社のSQL Server 2008 R2データベース内のテーブルのカップルで、伝統的な列並んでXML列を使用します。SQL XML - 存在:より良い方法がありますか?

<bridging> 
    <project id="43" source="true" /> 
    <project id="48" source="false" /> 
    <project id="99" source="false" /> 
    <project id="123" source="false" /> 
</bridging> 

その後、我々は.existでストアドprocsのを使用して、これらのテーブルからデータを選択WHERE句のXPathクエリ、次のように:

SELECT 
    e.ID, 
    e.ProjectsBridge, 
    e.Quantity, 
    e.Rate, 
    e.UOMID, 
    u.Name as UOM 
FROM  
    tblEstimator e LEFT OUTER JOIN 
    tblUnitOfMeasure u ON u.ID = e.UOMID 
WHERE 
    (e.ProjectsBridge.exist('//bridging/project/@id[. = sql:variable("@ProjectID")]') = 1 OR 
    @ProjectID IS NULL) 

をこれは、小さなデータセットで非常にうまく動作しますが、データセットより大きく、より遅く、これは取得 - 上記の例のデータセットに優に超える2分を実行しています百万を超えるレコード

したがって、このクエリを実行するためのより良い、より高速な方法があるかどうかは疑問です。

XMLスキーマを列に適用すると大きな違いがありますか?

+0

私はどのくらいの大きさのXML文書あなたはデータベース内にありますが、XPathの観点からは、子孫 - または - 自己軸(すなわち、 '//')は最もコストのかかる操作の1つです。 XPathを '/ bridging/project [@ id = sql:variable( "@ ProjectID")]'に変更して、これが少し高速化するかどうか確認してください。私はスキーマを使用することでスピードアップできるのかどうかわかりませんが、私の直感はそうではないということです。私はそれがスキーマに従って有効でないデータベース文書に挿入するのを妨げると思う。 – Pawel

+0

私はスキーマを適用しようとしましたが、ほとんど違いはありません。上のようにXPathを変更すると、138秒で1秒が得られます。しかし、返信いただきありがとうございます! – ReinhardtB

答えて

1

あなたが試すことができます物事のカップル:

は以上であってもよいですあなたの文脈で効率的です:

SELECT e.ID 
FROM tblEstimator e 
CROSS APPLY e.ProjectsBridge.nodes('/bridging/project') AS T(c) 
WHERE T.c.value('@id', 'INT') = @ProjectId 
+0

包括的な回答をお寄せいただきありがとうございます。私はこれらを順番に検討しています。これまでのところ、CROSS APPLY(私はOUTER APPLYに変更しなければなりませんでした。なぜなら、これはまっすぐな結合ではないからです)、138で4秒を節約します。一度試してみると、他のオプションについても報告します。再度、感謝します! – ReinhardtB

+0

プライマリXMLインデックスを追加すると、クエリーの実行時間が47秒に短縮され、63%の節約になります。ちなみに、 '/ bridging/project [@id' XPathは '/ bridging/project/@ id [。 – ReinhardtB

+0

セカンダリXMLインデックスを追加すると、 '// bridging/project ...'では実行時間が127秒、 '/ bridging/project ...'では92秒に戻ります。役に立たない。これまでのところ、主要なXMLインデックスFTWです! ... – ReinhardtB

関連する問題