此视图需要我执行HOURS:
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 server数据库调优,并创建了所有推荐的索引。再次执行视图15分钟后,我停了下来。
您是否可以向我提出有关我的查询的更明显的事情,以便更多地优化它并缩短执行时间?
答案 0 :(得分:1)
我认为你没有利用CTE的“共同”方面。首先尝试将表:millennium_dw_dev..F_ACCESSION_DAILY放入CTE中(如果可能,仅包含必要的字段和记录)。你的代码从这个表中选择了8次(这个表是本地的吗?)。
你的其他一些CTE被引用一次,但我可以看到一个是如何构建另一个。是的,他们可以帮助将复杂的查询分解为更多可管理的部分,但它可能对性能没有帮助。
此处的性能可能不是问题,但将这些硬编码的日期纳入某种假日/休息日表也会有所帮助。拥有date table可能是比所有这些计算更好的路线。
根据数据的大小,将其放入存储过程将允许使用索引临时表。