2

2つのテーブルがXMLtableありfilterTableます。

のデータに含まれるすべてのXMLtable.ID値が必要です。その内容はで一致します。XMLtableCol_XMyElementfilterColumnfilterTable

の各行のXMLには複数の'Col_Xが含まれている可能性があり、これらの要素のいずれかが。の値のいずれかと一致する場合に備えて必要です。MyElementIDfilterColumn

問題は、これらの列が実際にはvarchar(max)データ型であり、テーブル自体が巨大である(50GBの巨大なように)ことです。したがって、このクエリは可能な限り最適化する必要があります。

これが私が今いる場所の例です。これは、最初に一致する要素が探している要素の1つと等しい行を返すだけです。さまざまなエラーメッセージが多数あるため、これを変更して、同じ名前の要素すべてと比較することはできないようです。

SELECT ID, 
   CAST(Col_X AS XML).value('(//*[local-name()=''MyElement''])', N'varchar(25)') 
FROM  XMLtable

...そして結果をと比較しますfilterTable。これにはすでに5分以上かかります。

私が達成しようとしているのは、次のようなものです。

SELECT ID
FROM XMLtable
WHERE CAST(Col_X AS XML).query('(//*[local-name()=''MyElement''])') 
   IN (SELECT filterColumn FROM filterTable)

私が現在これを達成できる唯一の方法は、LIKE演算子を使用することです。これには、1000倍の時間がかかります。

さて、明らかに、列のデータ型などの変更を開始するオプションはありません。これは私が取り組まなければならないものです。:)

4

3 に答える 3

4

これを試して:

SELECT
  ID,
  MyElementValue
FROM 
  (
    SELECT ID, myE.value('(./text())[1]', N'VARCHAR(25)') AS 'MyElementValue'
    FROM XMLTable
      CROSS APPLY (SELECT CAST(Col_X AS XML)) as X(Col_X)
      CROSS APPLY X.Col_X.nodes('(//*[local-name()="MyElement"])') as T2(myE)
  ) T1
WHERE MyElementValue IN (SELECT filterColumn FROM filterTable)

この:

SELECT
  ID,
  MyElementValue
FROM 
  (
    SELECT ID, myE.value('(./text())[1]', N'VARCHAR(25)') AS 'MyElementValue'
    FROM XMLTable
      CROSS APPLY (SELECT CAST(Col_X AS XML)) as X(Col_X)
      CROSS APPLY X.Col_X.nodes('//MyElement') as T2(myE)
  ) T1
WHERE MyElementValue IN (SELECT filterColumn FROM filterTable)

アップデート

ここで説明されていることを経験していると思います。計算スカラー、式、および実行プランのパフォーマンス。XMLへのキャストは、関数の呼び出しごとに延期されvalueます。行う必要のあるテストは、のデータ型をに変更することCol_XですXML

それがオプションでない場合は、XMLTableからXML列を持つ一時テーブルに必要な行をクエリし、XMLにキャストする必要なしに一時テーブルに対して上記のクエリを実行できます。

CREATE TABLE #XMLTable
(
  ID int,
  Col_X xml
)

INSERT INTO #XMLTable(ID, Col_X)
SELECT ID, Col_X
FROM XMLTable

SELECT
      ID,
      MyElementValue
    FROM 
      (
        SELECT ID, myE.value('(./text())[1]', N'varchar(25)') AS 'MyElementValue'
        FROM #XMLTable
          CROSS APPLY Col_X.nodes('//MyElement') as T2(myE)
      ) T1
    WHERE MyElementValue IN (SELECT filterColumn FROM filterTable)


DROP TABLE #XMLTable
于 2012-10-02T15:31:32.790 に答える
1

あなたはこのようなことを試すことができます。それは少なくとも機能的にあなたが望むことをする、と私は信じています。データセットを使用してそのパフォーマンスを経験的に調査する必要があります。

SELECT ID
FROM 
( 
   SELECT xt.ID, CAST(xt.Col_X AS XML) [content] FROM XMLTable AS xt
) AS src
INNER JOIN FilterTable AS f
ON f.filterColumn IN 
(
   SELECT 
      elt.value('.', 'varchar(25)')     
   FROM src.content.nodes('//MyElement') AS T(elt)
)
于 2012-09-28T13:29:09.490 に答える
0

私はついにこれを機能させ、予想よりもはるかに優れたパフォーマンスを実現しました。以下は、5〜6分で最終的に正しい結果を生成したスクリプトです。

SELECT ID, myE.value('.', N'VARCHAR(25)') AS 'MyElementValue'
FROM (SELECT ID, CAST(Col_X AS XML) AS Col_X
    FROM XMLTable) T1
CROSS APPLY Col_X.nodes('(//*[local-name()=''MyElement''])' T2(myE)
WHERE myE.value('.', N'varchar(25)') IN (SELECT filterColumn FROM filterTable)

人々の助けに感謝します!

于 2012-10-02T13:26:57.277 に答える