web-dev-qa-db-fra.com

Performance CTE récursive

Besoin d'aide avec des performances CTE récursives. Ci-dessous CTE fonctionne très lentement car il essaie de tirer des données héritachiques de manière rectanive. La table est grande avec chaque identifiant racine ayant jusqu'à 3 articles récursifs. Il pourrait y avoir environ 200000 ou plus d'identifiant de racine. Je sais que les CTE récursives sont lentes pour un énorme jeu de données comme pour chaque voix racécronnée dans l'ancre, cela irait de manière récursive.

Schéma:

Create table RootItem (ItemId int primary key, RootIt int , insertdate datetime)

Le tableau ci-dessus a plus de 1 million de lignes.

Query 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
)

Nous ne pouvons pas modifier le schéma de table et utiliser Heirarchyid. J'ai essayé alors que la boucle aussi mais c'est lent aussi.

Y a-t-il une autre façon que je puisse optimiser cette requête?

 ; 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' 

Je travaille également avec BI Group pour modifier la logique de la requête et filtrer les données dans CTE elle-même du déplacement du couple de jointures et de critères à CTE .. Merci pour tous les commentaires.

8
njvds

Vous dites que la hiérarchie est modifiée. Vraisemblablement, tandis que cette opération est en cours d'exécution, il y a une certaine quantité de blocage qui se déroule alors?

Même si la hiérarchie change, les racines des articles changent-t-il?

Avez-vous examiné le temps qu'il faudrait pour simplement faire la table de mappage de root à l'article et indexer?

J'aimerais voir le plan d'exécution pour voir ce qui se passe - le CTE doit être bobouré, mais comme une table matérialisée manuelle et indexée, cela pourrait mieux fonctionner dans les étapes ultérieures.

Même avec une activité lourde, il me semble que quelqu'un doit être bloqué si les opérations DML modifient des données que ce processus lisait.

Je vais donc envisager de prendre un instantané de la hiérarchie.

En outre, vous avez un certain nombre d'autres jointures intérieures - vous devriez revoir si elle est, en fait, les CTES du tout et qu'il y ait des indices qui manquent de faire des jointures efficaces. Le plan d'exécution devrait vous dire ça.

Vous semblez avoir assez de choses dans la clause WHERE qui pourrait aider à réduire certaines opérations (et à déterminer les indices pourraient être les meilleurs)), mais il est difficile de dire sans regarder le plan d'exécution ni les index.

3
Cade Roux