0

このビューの実行には数時間かかります:

USE [SalesDWH]
GO

/****** Object:  View [dbo].[FirstLastEstablished]    Script Date: 10/29/2012 15:12:47 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER view [dbo].[FirstLastEstablished] as


with cte_min as(

select 
      a.client_id
      ,a.specimen_source
      ,a.received_date
from
      millennium_dw_dev..F_ACCESSION_DAILY a
join
            (select distinct
                  f.client_id
                  ,f.received_date
                  ,f.accession_daily_key
            from 
                  millennium_dw_dev..F_ACCESSION_DAILY f
            join 
                  (select CLIENT_ID, MIN(received_date) MinRecDate
                  from millennium_dw_dev..F_ACCESSION_DAILY
                  group by CLIENT_ID) i
            on f.CLIENT_ID=i.CLIENT_ID
            and f.RECEIVED_DATE=i.MinRecDate) b
on    
      a.ACCESSION_DAILY_KEY=b.ACCESSION_DAILY_KEY 

)

,
cte_max as 
(

select 
      a.client_id
      ,a.specimen_source
      ,a.received_date
from
      millennium_dw_dev..F_ACCESSION_DAILY a
join
            (select distinct
                  f.client_id
                  ,f.received_date
                  ,f.accession_daily_key
            from 
                  millennium_dw_dev..F_ACCESSION_DAILY f
            join 
                  (select CLIENT_ID, max(received_date) MaxRecDate
                  from millennium_dw_dev..F_ACCESSION_DAILY
                  group by CLIENT_ID) i
            on f.CLIENT_ID=i.CLIENT_ID
            and f.RECEIVED_DATE=i.MaxRecDate) b
on    
      a.ACCESSION_DAILY_KEY=b.ACCESSION_DAILY_KEY 

)
,


cte_est as

(

select distinct client_id, MLIS_DATE_ESTABLISHED
from millennium_dw_dev..D_CLIENT
where REC_ACTIVE_FLG=1
and MLIS_DATE_ESTABLISHED is not null
)

,

mainQuery as(
select distinct
      f.client_id
      ,cmin.specimen_source first_specimen_source
      ,cmin.received_date first_received
      ,cmax.specimen_source last_specimen_source
      ,cmax.received_date last_received
      ,cest.MLIS_DATE_ESTABLISHED MLIS_DATE_ESTABLISHED
from millennium_dw_dev..F_ACCESSION_DAILY f
left join cte_max cmax
on cmax.CLIENT_ID=f.CLIENT_ID
left join cte_min cmin
on cmin.CLIENT_ID=f.CLIENT_ID
left join cte_est cest
on cest.CLIENT_ID=f.CLIENT_ID
)
,
DateDifferences
as

(
SELECT
client_id,
   (DATEDIFF(dd, MLIS_DATE_ESTABLISHED,first_received) + 1)
  -(DATEDIFF(wk, MLIS_DATE_ESTABLISHED,first_received) * 2)
  -(CASE WHEN DATENAME(dw, first_received) = 'Sunday' THEN 1 ELSE 0 END)
  -(CASE WHEN DATENAME(dw, MLIS_DATE_ESTABLISHED) = 'Saturday' THEN 1 ELSE 0 END)
 -(case when cast('01/01/2008 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('05/26/2008 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('07/04/2008 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('09/01/2008 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('11/27/2008 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('12/25/2008 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('01/01/2009 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('05/25/2009 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('07/03/2009 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('09/07/2009 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('11/26/2009 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('12/25/2009 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('01/01/2010 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('05/31/2010 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('07/05/2010 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('09/06/2010 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('11/25/2010 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('12/24/2010 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('01/03/2011 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('05/30/2011 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('07/04/2011 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('09/05/2011 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('11/24/2011 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('12/26/2011 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('01/02/2012 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('05/28/2012 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('07/04/2012 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('09/03/2012 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('11/22/2012 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)
-(case when cast('12/25/2012 ' as date) between MLIS_DATE_ESTABLISHED and first_received then 1 else 0 end)


   DifferenceExcludingWeekends
  from
  mainQuery
)
,
Territory 
as
(
select distinct c.client_id,c.MLIS_TERRITORY,s.REGION_NAME
from millennium_dw_dev..D_CLIENT c
left join millennium_dw_dev..D_SALES_HIERARCHY s
on s.TERRITORY_NAME=c.MLIS_TERRITORY
where c.REC_ACTIVE_FLG=1
and s.REC_ACTIVE_FLG=1

)

select mainQuery.*,d.DifferenceExcludingWeekends,Territory.MLIS_TERRITORY,Territory.REGION_NAME
from mainQuery
left join DateDifferences d
on mainQuery.CLIENT_ID=d.CLIENT_ID
left join Territory
on mainQuery.CLIENT_ID=Territory.CLIENT_ID

GO

これでSQLサーバーデータベースのチューニングを行い、推奨されるすべてのインデックスを作成しました。ビューを再度実行してから 15 分後に停止しました。

クエリをさらに最適化し、実行時間を改善するために、クエリについて親切に指摘できる明らかな点はありますか?

4

1 に答える 1

1

CTEの「共通」の側面を利用しているとは思いません。table: millennium_dw_dev..F_ACCESSION_DAILY を最初に CTE に入れてみてください (可能であれば必要なフィールドとレコードのみ)。あなたのコードは、このテーブルから 8 回選択します (そして、このテーブルはローカルですか?)。

他の CTE のいくつかは一度参照されていますが、一方が他方の上にどのように構築されているかがわかります。はい、複雑なクエリをより管理しやすい部分に分割するのに役立ちますが、パフォーマンスには役立たない場合があります.

ここではパフォーマンスは問題にならないかもしれませんが、これらのハードコードされた日付を何らかの休日/休日テーブルに入れることも同様に役立ちます。日付テーブルを持つことは、これらすべての計算よりも優れた方法かもしれません.

データのサイズによっては、これをストアド プロシージャに入れると、インデックス付き一時テーブルを使用できるようになります。

于 2012-10-30T19:23:37.163 に答える