Rendimiento recursivo de CTE

8

Necesita ayuda con el rendimiento recursivo de CTE. Por debajo de CTE se ejecuta muy lentamente, ya que está tratando de extraer datos jerárquicos de manera recusiva. La tabla es grande con cada ID de raíz que tiene hasta 3 itemid recursivos. Podría haber alrededor de 200000 o más ID de raíz. Sé que los CTE recursivos son lentos para un gran conjunto de datos, ya que para cada rootid en el anclaje se recidiría de forma recursiva.

Esquema:

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

La tabla de arriba tiene más de 1 millón de filas.

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

No podemos modificar el esquema de la tabla y usar heirarchyid. Intenté while loop también pero eso también es lento.

¿Hay alguna otra forma de optimizar esta consulta?

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

También estoy trabajando con el grupo de BI para cambiar la lógica de consulta y filtrar datos en cte de mover un par de uniones y criterios para cte. Gracias por todos los comentarios.

njvds
fuente
2
¿Por qué necesitas todas las jerarquías? ¿No debería haber un lugar en algún lugar para que solo calcules los registros que pretendes usar? Seguramente no necesita construir millones de jerarquías cada vez que ejecuta esto.
HLGEM
Este es un informe colateral que se ejecuta entre 5 y 6 veces en un horario comercial y debe ejecutarse en todo el conjunto de datos. Podría haber precargado los datos si los datos eran estáticos o no se insertan con frecuencia, pero en este caso se ejecutan operaciones frecuentes de DML en esta tabla en DB.
njvds
¿Qué índices tienes en esta tabla?
ypercubeᵀᴹ
ItemID es la clave principal y también hay un índice no agrupado en itemid y rootid.
njvds
1
Tienes que mostrar la consulta que estás usando realmente. Como está ahora, todo lo que hace es una forma complicada de devolver todos los ItemID de la tabla. El CTE recursivo no agrega ningún valor.
Mikael Eriksson

Respuestas:

3

Dices que la jerarquía se modifica. Presumiblemente, mientras se ejecuta esta operación, ¿se está produciendo algún bloqueo?

Incluso si la jerarquía está cambiando, ¿están cambiando las raíces de los elementos?

¿Has mirado el tiempo que llevaría hacer la tabla de mapeo de raíz a elemento e indexarla?

Me gustaría ver el plan de ejecución para ver qué está sucediendo: el CTE debe ponerse en cola, pero como una tabla indexada y materializada manualmente podría funcionar mejor en los pasos posteriores.

Incluso con una gran actividad, me parece que alguien tiene que ser bloqueado si las operaciones DML están cambiando los datos que este proceso está leyendo.

Por lo tanto, consideraría tomar una instantánea de la jerarquía.

Además, tiene una serie de otras UNIONES INTERNAS: debe revisar si, de hecho, se trata de CTE y si hay algún índice que falte para que esas uniones sean efectivas. El plan de ejecución debería decirte eso.

Parece que tiene bastantes cosas en la cláusula WHERE que podrían ayudar a reducir algunas operaciones (y determinar qué índices podrían ser los mejores)), pero es difícil saberlo sin mirar el plan de ejecución o los índices.

Cade Roux
fuente
¿Por qué una operación DML bloquearía SELECT? ¿SQL Server sigue siendo tan limitado?
a_horse_with_no_name
@a_horse_with_no_name msdn.microsoft.com/en-us/library/ms173763.aspx es posible pero el usuario mencionó que hay una gran actividad, por lo que necesitaría considerar su estrategia
Cade Roux