sql >> データベース >  >> RDS >> Sqlserver

XMLサーバーXMLパフォーマンスの最適化

    私はあなたに1つの答えと1つの推測を与えることができます:

    まず、宣言されたテーブル変数を使用してモックアップします シナリオ:

    DECLARE @tbl TABLE(s NVARCHAR(MAX));
    INSERT INTO @tbl VALUES
    (N'<root>
        <SomeElement>This is first text of element1
            <InnerElement>This is text of inner element1</InnerElement>
            This is second text of element1
        </SomeElement>
        <SomeElement>This is first text of element2
            <InnerElement>This is text of inner element2</InnerElement>
            This is second text of element2
        </SomeElement>
    </root>')
    ,(N'<root>
        <SomeElement>This is first text of elementA
            <InnerElement>This is text of inner elementA</InnerElement>
            This is second text of elementA
        </SomeElement>
        <SomeElement>This is first text of elementB
            <InnerElement>This is text of inner elementB</InnerElement>
            This is second text of elementB
        </SomeElement>
    </root>');
    

    -このクエリは、 sub-selectからキャストされたXMLを読み取ります 。 CTEを使用する場合があります 代わりに、これは構文糖衣のみである必要があります...

    SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
          ,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
          ,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
          ,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
    FROM (SELECT CAST(s AS XML) FROM @tbl) AS tbl(TheXml)
    CROSS APPLY TheXml.nodes(N'/root/SomeElement') AS A(se);
    

    --2番目の部分では、テーブルを使用して型指定されたXMLを書き込み、そこから読み取ります:

    DECLARE @tbl2 TABLE(x XML)
    INSERT INTO @tbl2
    SELECT CAST(s AS XML) FROM @tbl;
    
    SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
          ,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
          ,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
          ,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
    FROM @tbl2 t2
    CROSS APPLY t2.x.nodes(N'/root/SomeElement') AS A(se);
    

    /text()が選ばれる理由 /text()がない場合よりも高速 ?

    私の例を見ると、要素のコンテンツはすべてです。 開始タグから終了タグまでtext() 要素のフローティングテキスト これらのタグの間。これは、上記の選択の結果で確認できます。 text() ツリー構造に個別に格納された部分の1つです。 実際に(次のセクションを読んでください)。それを取得するには、ワンステップアクション 。それ以外の場合は、複雑な構造を分析して、開始タグとそれに対応する終了タグの間のすべてを見つける必要があります-text()以外に何もない場合でも 。

    XMLを適切なタイプで保存する必要があるのはなぜですか?

    XMLは、ばかげた余分な文字を含む単なるテキストではありません。複雑な構造の文書です。 XMLは表示されるテキストとして保存されません 。 XMLはツリー構造で保存されます。 XMLを表す文字列を実際のXMLにキャストするときはいつでも、この非常にコストのかかる作業を行う必要があります。 XMLが表示されると(またはその他の出力)、表現する文字列が最初から(再)構築されます。

    プレキャストアプローチの方が速いのはなぜですか

    これは推測です...
    私の例では、両方のアプローチはまったく同じであり、(ほぼ)同じ実行プランにつながります。
    SQL Serverは、期待どおりにすべてを機能させるわけではありません。これは、これを実行するよりも、これを実行した後、これを実行する!と述べる手続き​​型システムではありません。 。あなたはエンジンにあなたが望むものを伝え、そしてエンジンはこれを最もよくする方法を決定します。そして、エンジンはこれでかなり良いです!
    実行が開始する前に、エンジンはアプローチのコストを推定しようとします。 CONVERT (またはCAST )はかなり安価な操作です。エンジンは、呼び出しのリストを調べて、必要に応じてキャストを何度も繰り返すことを決定する可能性があります。これは、派生テーブルの高価な作成よりも安価であると考えているためです...

    >


    1. MySQL:レコードが存在しない場合でも、範囲内のすべての日付を選択します

    2. 初心者向けのSQLOR演算子

    3. 更新ステートメントでのウィンドウ関数の使用

    4. FILESTREAM対応データベースのバックアップと復元