再帰的なCTEパフォーマンスについてサポートが必要です。 CTE以下では、階層データを再帰的に取得しようとしているため、実行速度が非常に遅くなっています。テーブルは大きく、すべてのルートIDに最大3つの再帰的なアイテムIDがあります。約200000以上のルートIDが存在する可能性があります。アンカーのすべてのrootidは再帰的にitemidになるため、再帰CTEは巨大なデータセットでは遅いことを知っています。
スキーマ:
Create table RootItem (ItemId int primary key, RootIt int , insertdate datetime)
上記の表には100万行を超える行があります。
CTEクエリ:
; With rootcte as
( select itemid from RootItem where rootid is null
union all
select r.itemid as RootId , i.itemid from RootItem i join rootcte r
on i.rootid = r.itemid
)
テーブルスキーマを変更してheirarchyidを使用することはできません。私もwhileループを試しましたが、それも遅いです。
このクエリを最適化できる他の方法はありますか?
; With rootcte as
( select itemid from RootItem where rootid is null
union all
select r.itemid as RootId , i.itemid from RootItem i join rootcte r
on i.rootid = r.itemid
)
SELECT
Cust.CustomerID
, Cust.BusinessName
, sCust.RegionCustomerID
, ord.OrderID
, ord.OrderItemID
, prd.ProductCode
, rc.itemid
, rc.rootid
, mf.FileID
FROM
vw_Customer Cust
INNER JOIN SrcCustomer scust ON Cust.CustomerID = sCust.RegionCustomerID
INNER JOIN OrderItem ord ON Cust.MasterCustomerID = ord.MasterCustomerID
INNER JOIN Product ON ord.ProductID = Product.ProductID
INNER JOIN rootcte rc ON ord.RootOrderId = rc.Rootid
INNER JOIN MFolder mf ON mf.mfolderid = rc.itemid
INNER JOIN MVersion mv ON mv.mfolderversionid = mf.mfolderid
WHERE ord.IsActive = 1 and product.IsSelling = 1 and mf.fileid in (23,45,29)
and mv.isdeleted = 'N'
私はまた、BIグループと連携して、結合の結合と基準の移動のcte自体のcte自体のクエリロジックを変更し、データをフィルター処理しています。すべてのコメントをありがとう。
階層が変更されると言います。おそらく、この操作の実行中に、ブロックが発生していますか?
階層が変わっても、アイテムのルーツは変わりますか?
ルートからアイテムへのマッピングテーブルを作成してインデックスを作成するのにかかる時間を見ましたか?
何が起こっているのかを確認するための実行計画を見たい-CTEはスプールされるはずですが、手動でマテリアライズされたインデックス付きのテーブルとして、後の手順でパフォーマンスが向上する可能性があります。
アクティビティが重い場合でも、このプロセスが読み取っているデータをDML操作が変更している場合、誰かをブロックする必要があるように思えます。
したがって、階層のスナップショットを取ることを強く検討します。
さらに、他にも多数のINNER JOINがあります。それが実際にCTEであるかどうか、およびこれらの結合を有効にするために欠落しているインデックスがあるかどうかを確認する必要があります。実行計画はそれを教えてくれるはずです。
一部の操作を削減するのに役立つ可能性がある(そしてどのインデックスが最適であるかを判断する)WHERE句にかなりの数のものが含まれているように見えますが、実行プランやインデックスを調べないと分からないでしょう。