繁体   English   中英

提高 CTE 的性能

[英]Improving Performance of CTE

我需要一份报告,计算不同表格中的一些值。
我正在使用 CTE 和子查询进行计算,但查询速度很慢。
我尝试了一些尝试来提高性能,但没有成功。
实际查询有更多列,但我复制了其中的一部分以了解我的查询结构。
感谢帮助。

begin
with CTE_FirmList
(
    FirmId,
    FirmName,
    StartDate,
    EndDate,
    TgId,
    TgName,
    TgCity,
    ProjectName
)
as
(
    select 
        distinct f.Id FirmId,
        f.Name FirmName,
        f.StartDate,
        f.EndDate,
        t.Id TgId,
        t.Name TgName,
        c.Name TgCity,
        p.Name ProjectName
    from Firm f
        left join Tg t on t.Id = f.TgId
        left join City c on c.Id=t.CityId 
        left join Country co on co.Id=f.CountryId
        left join FirmProject p on p.FirmId=f.Id
)

select
    FirmId,
    FirmName,
    
    (select COUNT(0) 
    from FirmPersonnel p 
        inner join CTE_FirmList f on f.FirmId=p.FirmId
    where f.FirmId=qq.FirmId
    ) TotalPersonnelCount,
    
    (select COUNT(0) 
    from FirmPersonnel p 
        inner join CTE_FirmList f on f.FirmId=p.FirmId 
    where f.FirmId=qq.FirmId and p.PersonnelType in (1) 
    ) PersonnelCount1,

    (select COUNT(0) 
    from FirmPersonnel p 
        inner join CTE_FirmList f on f.FirmId=p.FirmId 
    where f.FirmId=qq.FirmId and p.PersonnelType in (2) 
    ) PersonnelCount2,
            
    (select count(p.Id) 
    from FirmProject p 
    where p.FirmId=qq.FirmId
    ) TotalProjectCount,
    
    (select count(p.Id) 
    from FirmProject p 
    where p.FirmId=qq.FirmId
        and p.ProjeStatus in (1)
    ) ProjectCount1,
    
    (select count(p.Id) 
    from FirmProject p 
    where p.FirmId=qq.FirmId
        and p.ProjeStatus in (2)
    ) ProjectCount2
from CTE_FirmList qq
where ProjectName like '%search condition%'
order by TgCity,TgName,FirmName
end

这是示例数据和所需的 output:

tg
公司
人员项目输出

您绝对可以简化查询。 这有点难以理解,但是像这样的东西应该有更好的性能:

select f.FirmId, f.FirmName,
       p.TotalPersonnelCount, p.PersonnelCount1, p.PersonnelCount2
       count(distinct ProjectId) as TotalProjectCount,
       count(distinct case when ProjectStatus = 1 then ProjectId end) as ProjecctCount1,
       count(distinct case when ProjectStatus = 2 then ProjectId end) as ProjecctCount2
from (select f.Id as FirmId, f.Name as FirmName, f.StartDate, f.EndDate,
             t.Id TgId, t.Name as TgName, c.Name as TgCity,
             p.Name as ProjectName, p.ProjectId, p.status
      from Firm f left join
           Tg t
           on t.Id = f.TgId join
           City c
           on c.Id = t.CityId left join
           Country co
           on co.Id = f.CountryId left join
           FirmProject p
           on p.FirmId = f.Id
       where p.name like '%search condition%'
      ) fp join
      (select p.FirmId, count(*) as TotalPersonnelCount,
              sum(case when PersonnelType in (1) then 1 else 0 end) as PersonnelCount1, 
              sum(case when PersonnelType in (2) then 1 else 0 end) as PersonnelCount2
       from FirmPersonnel p 
       group by fp.FirmId 
      ) p
      on fp.FirmId = p.FirmId
group by FirmId, FirmName
order by FirmName

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM