You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归CTE性能优化及ID分离度字段实现问题(大表场景)

递归CTE性能优化与ID分离度计算问题

现有大型数据表,核心字段包含ID、PreviousID(关联父级ID,根节点为null)、Location等。需求为:输入任意ID,检索其对应的原始ID(即根节点ID)及原始ID关联的位置,同时计算ID与原始ID的分离度(根节点分离度为0,每向上追溯一层分离度加1,比如ID=2分离度0,ID=4分离度2,ID=9分离度1)。

一、已解决的分离度计算问题

该问题已由@ValNik解答,以下是简化实现脚本:

DECLARE @IDs TABLE (
  ID INTEGER
  ,PreviousID INTEGER
  ,Location INTEGER
)

INSERT INTO @IDs
SELECT           2,null,1235
UNION ALL SELECT 3,2,1236
UNION ALL SELECT 4,3,1239
UNION ALL SELECT 8,null,1237
UNION ALL SELECT 9,8,1234
UNION ALL SELECT 10,9,1235

Select * from @IDs


DECLARE @ORDERID Table (OrderID nvarchar (100))
Insert into @ORDERID values
('4')
,('9')
,('2')

;WITH q AS (
    SELECT  ID, PreviousID,Location
    FROM    @IDs
    where ID in (select OrderID from @ORDERID) 
       -- or PreviousID in (select OrderID from @ORDERID)
    UNION ALL 
    SELECT  q.ID, u.PreviousID,q.Location
    FROM    q
            INNER JOIN @IDs u ON u.ID = q.PreviousID
            --and q.ID in (select OrderID from @ORDERID)
)


,CTE_Original as
(
SELECT  q.ID
        ,q.Location
        ,case when Min(PreviousID) is null then ID
                else min(PreviousID) end as OriginalID

FROM    q
GROUP BY q.ID,q.Location
)

Select CTE_Original.*,Original.Location as OriginalLocation from CTE_Original 
left join @IDs Original on Original.ID = CTE_Original.OriginalID
                        
where CTE_Original.ID in (select OrderID from @ORDERID)
order by ID

二、当前性能优化需求

实际场景中,上述示例的@IDs对应临时表#CTE_ORDERID,该表由多表关联生成,包含300万+行数据,生成插入耗时约20秒,但递归CTEq执行耗时超过10分钟。在无法查看执行计划的情况下,如何优化性能?

实际脚本如下:

DECLARE @ORDERID Table (OrderID nvarchar (100))
Insert into @ORDERID values
('119309645')
,('115821862')
,('112942594')

;


Drop table if exists #CTE_OrderID

;
;WITH CTE_OrderID AS (
    SELECT ORDER_MED.ORDER_MED_ID as CURRENT_ORDERID
        ,ORDER_MED.CHNG_ORDER_MED_ID as PREV_ORDERID
        ,CLARITY_DEP.DEPARTMENT_NAME    as WRITTEN_LOCATION
        ,ORDER_MED.ORDERING_DATE        as WRITTEN_DATE
    FROM Clarity_PRD_Report.dbo.ORDER_MED (nolock)  
        LEFT JOIN Clarity_PRD_Report.dbo.CLARITY_DEP (nolock) on ORDER_MED.PAT_LOC_ID = CLARITY_DEP.DEPARTMENT_ID
    GROUP BY ORDER_MED_ID --,PAT.PAT_MRN_ID
        ,ORDER_MED.CHNG_ORDER_MED_ID
        ,CLARITY_DEP.DEPARTMENT_NAME    
        ,ORDERING_DATE  
        )
Select * 
Into #CTE_OrderID
From CTE_OrderID
;
With q as (
    Select CURRENT_ORDERID
           ,PREV_ORDERID
           ,PREV_ORDERID as Last_ORDERID
           ,WRITTEN_LOCATION
           ,WRITTEN_LOCATION as ORIGINAL_WRITTEN_LOCATION
           ,WRITTEN_DATE
           ,WRITTEN_DATE as ORIGINAL_WRITTEN_DATE
           ,0 NumOfTimesRewrite
           
           
    From #CTE_OrderID
        where CURRENT_ORDERID in (Select OrderID from @ORDERID) 

    UNION ALL 
    SELECT  q.CURRENT_ORDERID
            ,u.PREV_ORDERID
            ,q.PREV_ORDERID LAST_ORDERID
            ,q.WRITTEN_LOCATION
            ,u.WRITTEN_LOCATION
            ,q.WRITTEN_DATE
            ,u.WRITTEN_DATE
            ,NumOfTimesRewrite+1

    FROM    q
            inner JOIN #CTE_OrderID u ON u.CURRENT_ORDERID = q.PREV_ORDERID
            --and q.ORDER_MED_ID in (select orderID from @ORDERID)
)

Select CURRENT_ORDERID
    ,Coalesce(LAST_ORDERID,CURRENT_ORDERID) as ORIGINAL_ORDERID
    ,WRITTEN_LOCATION
    ,ORIGINAL_WRITTEN_LOCATION
    ,WRITTEN_DATE
    ,ORIGINAL_WRITTEN_DATE
    ,NumOfTimesRewrite

FROM q
WHERE PREV_ORDERID is null
order by CURRENT_ORDERID

内容的提问来源于stack exchange,提问作者T340B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:44:55