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.
Respuestas:
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.
fuente