Sql server 优化包含CTE和TESTERABLE的sql查询

Sql server 优化包含CTE和TESTERABLE的sql查询,sql-server,Sql Server,我正在努力优化查询的性能。我已经实现了两个CTE,并创建了两个临时表。最后,我编写了一个组合查询,该查询在CTE上进行联合,并与temp表进行连接。我正在分享我在哪里定义CTE和组合查询的代码。我有以下查询,并希望就提高速度的最佳实践提出建议 ;with histTbl_CTE as ( select a.companyid, a.periodenddate, a.pricingdate,

我正在努力优化查询的性能。我已经实现了两个CTE,并创建了两个临时表。最后,我编写了一个组合查询,该查询在CTE上进行联合,并与temp表进行连接。我正在分享我在哪里定义CTE和组合查询的代码。我有以下查询,并希望就提高速度的最佳实践提出建议

;with histTbl_CTE 
as (
        select 
            a.companyid,
            a.periodenddate,
            a.pricingdate,
            fp.fiscalYear,
            fp.fiscalQuarter,
            pt.periodtypeId
        from (
            /* determine the cartesian product of periodenddate and pricingdate, assigning 
            a periodenddate to every pricing date that is less than the periodenddate */
                    select 
                            per.companyid, 
                            periodenddate, 
                            pric.pricingdate,
                            datediff(day, pricingdate, periodenddate) as peqdiffdate
                    from  #PeriodTbl per
                    join #PricingTbl pric
                    on (per.companyid = pric.companyid 
                            and per.periodenddate >= pric.pricingdate)
            ) a
        inner join (
                    /*find the different between the pricing date and the period end date */
                    select 
                            per.companyid,
                            periodenddate,
                            min(datediff(day, pricingdate, periodenddate)) minpeqdiffdate
                    from 
                    #PeriodTbl per
                    join #PricingTbl pric
                    on (per.companyid = pric.companyid
                            and per.periodenddate >= pric.pricingdate)
                    group by per.companyid, per.fiscalyear, per.fiscalquarter, periodenddate
            )b
        on a.companyid = b.companyid 
            and a.periodenddate = b.periodenddate
            and a.peqdiffdate = b.minpeqdiffdate
        left join ciqFinPeriod fp on a.companyId = fp.companyId
        left join ciqFinInstance fi on (a.periodenddate = fi.periodenddate
                                                    and fi.financialPeriodId = fp.financialPeriodId)
        left join ciqPeriodType pt on pt.periodTypeId = fp.periodTypeId
        where fi.latestforfinancialperiodflag = 1
            and latestfilingforinstanceflag = 1
            and pt.periodtypeid = 4
        group by a.companyid, a.periodenddate, a.pricingdate, fp.fiscalYear, fp.fiscalQuarter, pt.periodtypeid
        ), 
recentTbl_CTE 
        as (
        --/* use the same methodology from above to find the most recent dates */
        select 
            temp.companyId,
            max(periodenddate) as periodenddate,
            max(peqdate) as pricingDate,
            x.adjFY as fiscalYear,
            x.adjFQ as fiscalQuarter,
            periodTypeId = NULL
        from(
            select
                    a.companyId,
                    a.periodenddate,
                    a.peqdate,
                    b.minpeqdiffdate
            from(
                    select 
                            mc.companyId,
                            mc.pricingDate as periodenddate,
                            peq.pricingDate as peqdate,
                            datediff(day, peq.pricingDate, mc.pricingDate) as peqdiffdate
                    from #MarketTbl mc
                    join #PricingTbl peq
                    on  (mc.companyId = peq.companyId
                            and mc.pricingDate >=peq.pricingDate)
                    group by mc.companyid, mc.pricingDate, peq.pricingDate
                    ) a
            inner join (
                    select 
                            mc.companyId,
                            mc.pricingdate as periodenddate,
                            min(datediff(day, peq.pricingDate, mc.pricingDate)) as minpeqdiffdate
                    from #MarketTbl mc
                    join #PricingTbl peq 
                    on (mc.companyId = peq.companyId
                            and mc.pricingDate >= peq.pricingDate)
                    group by mc.companyid, mc.pricingDate
                    ) b on 
                            a.companyId = b.companyId
                            and a.periodenddate = b.periodenddate
                            and a.peqdiffdate = b.minpeqdiffdate
                    ) temp
        join #futurePer x on x.companyId = temp.companyId
        group by temp.companyid, minpeqdiffdate, adjFY, adjFQ
        having minpeqdiffdate = 0
        )


/* combine all table and join the data*/
select
        combined.companyId,
        combined.periodenddate,
        combined.dataItemName,
        case when combined.dataItemName = 'priceMidUSD' then combined.dataItemidue/exR.currencyRateClose * 1
            when combined.dataItemName = 'sharesOutstanding' then combined.dataItemidue
            when combined.dataItemName = 'marketcaptrend' then combined.dataItemidue
            else combined.dataItemidue/exR.currencyRateClose * 1e6 end as dataItemidue,
        combined.fiscalYear,
        combined.fiscalQuarter,
        combined.periodTypeId,
        ctbl.tickerSymbol,
        ctbl.exchangeName,
        id.dataItemId
from(
        select
            companyId,
            pricingdate,
            periodenddate,
            currencyId,
            dataItemName,
            cast(dataItemidue as float) as dataItemidue,
            fiscalYear,
            fiscalQuarter,
            periodTypeId
        from(
            select 
                            a.companyId,
                            a.pricingdate,
                            c.currencyId, 
                            a.periodenddate,
                            cast(c.priceMid as nvarchar(100)) as priceMidUSD,
                            cast(d.marketCap as nvarchar(100)) as marketCapUSD,
                            cast((d.marketCap/nullif(prevmc.prevmarketCap,0)) - 1 as nvarchar(100)) as marketcaptrend,
                            cast(d.TEV as nvarchar(100)) as TEV,
                            cast(d.sharesOutstanding as nvarchar(100)) as sharesOutstanding,
                            a.fiscalYear,
                            a.fiscalQuarter,
                            a.periodTypeId
            from (
                    select       
                            companyid,
                            periodenddate,
                            pricingdate,
                            fiscalYear,
                            fiscalQuarter,
                            periodtypeId 
                    from histTbl_CTE

                    union all

                    select
                            companyId,
                            periodenddate,
                            pricingDate,
                            fiscalYear,
                            fiscalQuarter,
                            periodTypeId
                    from recentTbl_CTE
                            )a
            join #PricingTbl c
                    on (
                    c.pricingdate = a.pricingDate
                    and c.companyId = a.companyId )
            join #MarketTbl d
                    on (
                    d.companyId = a.companyId
                    and d.pricingDate = a.periodenddate)
            left join (
                    select a.companyId,
                            a.pricingDate,
                            a.prevperiod, 
                            b.marketcap as prevmarketcap
                    from(
                            select 
                                mc.companyid,
                                mc.pricingdate,
                                mc.pricingdate -365 as 'prevperiod'
                            from
                                ciqMarketCap mc
                            where 
                                mc.companyid in (select id from #companyId)
                            ) a
                    inner join (
                            select 
                                mc.companyId,
                                mc.pricingdate,
                                mc.marketcap
                            from #MarketTbl mc 
                            ) b
                            on (a.companyid = b.companyid
                            and a.prevperiod = b.pricingdate)
            ) prevmc
                    on (prevmc.companyid = d.companyid
                            and prevmc.pricingdate = d.pricingdate)

            group by a.companyid, a.periodenddate, a.pricingDate, a.fiscalYear, a.fiscalQuarter, a.periodtypeid, c.currencyId,
                            c.pricemid, d.marketCap, d.TEV, d.sharesOutstanding, prevmc.prevperiod, prevmc.prevmarketcap
            ) c
                    unpivot
                    (dataItemidue for dataItemName in
                            (TEV, marketCapUSD, sharesOutstanding, marketcaptrend, priceMidUSD)
                            ) as unpvt
        ) combined 
join #CompanyInfoTbl ctbl on ctbl.companyId = combined.companyId

如果不了解模式、索引和执行计划,就很难提供很多有用的建议。我只是想验证cte的使用方式,如果它们是有效的,公共表表达式不会优化您的查询,它只会使您的查询更具可读性。这个问题可能更适合。如果您同意您可以通过单击标志来移动>>应关闭….>>离题,因为..>>属于另一个堆栈交换站点。请看一些最热门的SQL问题,了解如何在该网站上提问。我是否需要将CTE的结果转储到临时表中并为列编制索引。这有助于提高性能吗