优化包含CTE和temptable的sql查询

时间:2017-06-20 11:23:59

标签: sql-server

我正致力于优化查询的性能。我已经实现了两个CTE以及创建了几个临时表。最后,我正在编写一个组合查询,它在CTE上进行联合并与临时表连接。我正在分享我在定义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

0 个答案:

没有答案