2016-05-31 2 views
-1

SQL Server 2005ストアドプロシージャを作成していますが、xmlの選択が非常に遅いです。XMLフィールドのSELECTが遅い

これは私のコードである:

INSERT INTO @T  
    SELECT DISTINCT 
     tr.ID, tr.Identificazione as identification, 
     ft.NumeroFattura, ft.IDFattura, 
     dbo.getInvoicePayedStatus(ft.IDFattura) 
    FROM 
     TestReport AS tr 
    INNER JOIN 
     Job AS j ON j.ID = tr.Job 
    INNER JOIN 
     Plan_Main AS pm ON pm.TESTREPORT = tr.ID 
    INNER JOIN 
     Fatture AS ft ON ft.IDFattura IN (SELECT T.N.value('(text())[1]','int') 
              FROM XMLDATA.nodes('InvoiceList/id') AS T(N)) 
WHERE 
    tr.DocumentStatus = 4 
    AND j.NomeCliente = @companyId 
    AND ft.IDFattura IS NOT NULL 
ORDER BY 
    tr.id ASC 

これは私のストアドプロシージャを遅くする部分である。

(SELECT T.N.value('(text())[1]','int') 
FROM pm.XMLDATA.nodes('InvoiceList/id') AS T(N)) 

XMLの例:

<PrecedentTask /> 
<UsedResources /> 
<InvoiceList> 
    <id>4350</id> 
</InvoiceList> 

の数行は "SQLの場所"(約30)の後に相対的に小さいが、クエリには8秒以上が必要です。

"IN"ではなく "="演算子で試してみましたが、パフォーマンスは素晴らしいです(1秒未満)。xmlの "invoiceList"に複数の行が含まれていると動作しません。

解決策はありますか?

+0

何か?また、選択クエリ 'dbo.getInvoicePayedStatus()'のスカラー関数がselectクエリによって返される各行に対して実行されていることも知っていますか? UDFを取り除き、結合を使用してください。 –

+0

FattureはPlan_Main.XMLData内のXMLとのみリンクされており、dbo.getInvoicePayedStatusが実行されていることを知っていますが、この機能が速いため問題ありません。 とにかく、等価演算子ではクエリ結果が高速であると言いました – Tiziano

+0

そして 'Fatture'テーブルのデータは、それを' Fatture'テーブルに結合する前に結合内のどのテーブルにもリンクされていますか?このテーブルを他のテーブルと結合して、最終的な結果セットを取得する必要がありますか?そうでなければ、他のテーブルと 'Fatture'テーブルの間のすべての結合の結果セットのクロス結合を与えています。これはあなたのクエリが遅い理由である可能性があります。 –

答えて

3

現在、クエリでは、次の表の間で一致する行が返されます。

TestReport as tr 
INNER JOIN Job  as j 
on j.ID = tr.Job   -- Only matching rows betwwen "TestReport" & "Job" 
INNER JOIN Plan_Main as pm 
on pm.TESTREPORT = tr.ID -- Only matching rows betwwen "TestReport" & "Plan_Main" 

しかし、あなたはそれが実際にcorss joinsresult setは、上記の結合とFattureから戻って上記のいずれかの表とFattureテーブル

とのNO定義された関係でFattureテーブルで上記の表を結合しますIDFatturaがXML文書内にあるテーブル。

あなたの問題は、XMLをシュレッディングするクエリではなく、JOINSと言います。

Fattureテーブルに結合するときにON句にリレーションシップを定義し、ON句またはwhere句で同じIN(サブクエリ)を使用してローをフィルタする必要があります。 `Fatture`が` JOINS`に他のテーブルのいずれかにリンクされているどのような...

FROM TestReport as tr 
INNER JOIN Job  as j on j.ID = tr.Job 
INNER JOIN Plan_Main as pm on pm.TESTREPORT = tr.ID 
INNER JOIN Fatture as ft on ft.IDFattura =   --<-- A column to join it back to any of the above tables       
WHERE tr.DocumentStatus = 4 
    and j.NomeCliente = @companyId 
    and ft.IDFattura is not null 
    and ft.IDFattura IN (SELECT T.N.value('(text())[1]','int') 
         FROM pm.XMLDATA.nodes('InvoiceList/id') AS T(N)) 
ORDER BY tr.id ASC 
関連する問題