none
递归的查询过程中去重复和递归的查询完毕之后再去重复,效率是一样的吗?还是不同? RRS feed

  • 问题

  • 使用cte递归查询有向无环图的邻接表,可能会查询到重复节点,表结构是(

     id int primary key identity(1,1),

    nodeId int,

    parentNodeID int,

    unique(nodeid,parentNodeId)

    )。或者有更好的表结构?

    那么如果要去重复并且追求性能的话,是在cte查询过程中把内部的union all 改成union或者是用group by ,还是查询完毕之后用distinct?或者这两种方式的性能效率是差不多的?还是查询完成后仅仅用distinct效率是最高的?有人能解释一下吗?



    • 已编辑 Trian555 2018年11月27日 8:35
    2018年11月27日 8:34

答案

  • Hi Trian555,

    虽然在递归中不可以使用distinct,但是可以使用开窗函数进行去重。

    with cte 
    as
    (
    select id from (select *, ROW_NUMBER()Over(PARTITION by id Order by id) qq from dbo.tree_path) as mm  where path in (1,4) and qq = 1
    union all
    select  a.id from dbo.tree_path as a
    inner join (select id from (select id ,ROW_NUMBER()Over(PARTITION by id Order by id) Rn from cte) as s where Rn = 1 ) as b
    on b.id=a.path
    )
    select * from cte

    查询完毕后用distinct,这个操作是在执行过重复操作之后然后进行的去重操作,而上述方法是直接在过程中进行去重,理论上上述方法的效率会高一点。但是最终还是要依据具体情况来看。

    Best Regards,

    Teige


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Trian555 2018年11月29日 11:59
    2018年11月28日 1:25
    版主
  • 如果重复率高,递归的次数多,最终产生的结构会很庞大,从这个角度看,先去重复列优

    但重复率不高,递归次数不多的话,每次处理都额外去重复效率反而更低了

    2018年11月29日 1:00
  • 如果数据量较大,建议先去重,放入表变量再递归。

    你可以试试用CTE看它会不会做假脱机,如果有假脱机,和用表变量是差不多的。


    想不想时已是想,不如不想都不想。

    • 已标记为答案 Trian555 2018年11月29日 11:59
    2018年11月29日 10:24
    版主

全部回复

  • CTEL 递归中无法去重,因为在递归用法中,不支持 DISTINCT 、 GROUP BY
    2018年11月27日 9:23
  • Hi Trian555,

    虽然在递归中不可以使用distinct,但是可以使用开窗函数进行去重。

    with cte 
    as
    (
    select id from (select *, ROW_NUMBER()Over(PARTITION by id Order by id) qq from dbo.tree_path) as mm  where path in (1,4) and qq = 1
    union all
    select  a.id from dbo.tree_path as a
    inner join (select id from (select id ,ROW_NUMBER()Over(PARTITION by id Order by id) Rn from cte) as s where Rn = 1 ) as b
    on b.id=a.path
    )
    select * from cte

    查询完毕后用distinct,这个操作是在执行过重复操作之后然后进行的去重操作,而上述方法是直接在过程中进行去重,理论上上述方法的效率会高一点。但是最终还是要依据具体情况来看。

    Best Regards,

    Teige


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Trian555 2018年11月29日 11:59
    2018年11月28日 1:25
    版主
  • 如果重复率高,递归的次数多,最终产生的结构会很庞大,从这个角度看,先去重复列优

    但重复率不高,递归次数不多的话,每次处理都额外去重复效率反而更低了

    2018年11月29日 1:00
  • 如果数据量较大,建议先去重,放入表变量再递归。

    你可以试试用CTE看它会不会做假脱机,如果有假脱机,和用表变量是差不多的。


    想不想时已是想,不如不想都不想。

    • 已标记为答案 Trian555 2018年11月29日 11:59
    2018年11月29日 10:24
    版主