2010-09-28 78 views
2

大家好SQL Server 2008中優化FULL JOIN與ISNULL報表

我希望有人能幫助我提高查詢我要定期運行。目前需要超過40分鐘才能執行。它在此期間使用完全分配的內存,但CPU使用率大多在2%-5%之間徘徊,每隔幾秒鐘跳到40%。

我有此表(簡化的示例):

CREATE TABLE [dbo].[dataTable] 
    (
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [dteEffectiveDate] [date] NULL, 
    [dtePrevious] [date] NULL, 
    [dteNext] [date] NULL, 
    [Age] [int] NULL, 
    [Count] [int] NULL 
    ) ON [PRIMARY] 

    GO 

這裏有一些輸入值:

INSERT INTO [YourDB].[dbo].[dataTable] 
      ([dteEffectiveDate] 
      ,[dtePrevious] 
      ,[dteNext] 
      ,[Age] 
      ,[Count]) 
    VALUES 
('2009-01-01',NULL,'2010-01-01',40,300), 
('2010-01-01','2009-01-01', NULL,40,200), 
('2009-01-01',NULL, '2010-01-01',20,100), 
('2010-01-01','2009-01-01', NULL,20,50), 
('2009-01-01',NULL,'2010-01-01',30,10) 
GO 

每個條目都有一個dteEffectiveDate字段。另外,每個都有一個dtePrevious和dteNext,它們反映最近的上一個/下一個生效日期的日期。現在我想要的是一個查詢,它將計算特定時間內連續時間段之間計數字段的中間值。

因此,例如,在上面的數據,40歲,我們有300在2009/01/01和200在2010/01/01所以查詢應該產生250

請注意,30歲只有一個入口,10。這是在2009/01/01。 2010/01/01沒有條目,但我們知道數據是在這個時候捕獲的,所以沒有什麼意味着在這個日期30是0。因此,查詢應該產生5.

爲了實現這一目的,我在表上使用了FULL JOIN,並使用ISNULL來選擇值。這裏是我的代碼:

SELECT 

    ISNULL(T1.dteEffectiveDate,T2.dtePrevious) as [Start Date] 
    ,ISNULL(T1.dteNext,T2.dteEffectiveDate) as [End Date] 
    ,ISNULL(T1.Age,T2.Age) as Age 
    ,ISNULL(T1.[Count],0) as [Count Start] 
    ,ISNULL(T2.[Count],0) as [Count End] 
    ,(ISNULL(T1.[Count],0)+ISNULL(T2.[Count],0))/2 as [Mid Count] 

    FROM 
    [ExpDBClient].[dbo].[dataTable] as T1 
    FULL JOIN [ExpDBClient].[dbo].[dataTable] as T2 

    ON 
    T2.dteEffectiveDate = T1.dteNext 
    AND T2.Age = T1.Age 

    WHERE ISNULL(T1.dteEffectiveDate,T2.dtePrevious) is not null 
    AND ISNULL(T1.dteNext,T2.dteEffectiveDate) is not null 

GO 

,輸出:

Start Date End Date Age Count Start Count End Mid Lives 
2009-01-01 2010-01-01 40 300   200   250 
2009-01-01 2010-01-01 20 100   50   75 
2009-01-01 2010-01-01 30 10   0   5 

它完美,但當我實際的數據,大約是7米記錄運行此,它需要長期痛苦來執行。

有沒有人有任何建議?

感謝
卡爾

+0

你有什麼指標在桌子上?每個年齡最多有2行? – 2010-09-28 12:28:43

+0

沒有指數。每個dteEffectiveDate每個年齡段只會有一個條目。因此,根據生效日期的數量,年齡出現的次數沒有上限。但是每個年齡段總是隻有dteEffectiveDate,dtePrevious和dteNext的組合。(這是簡化的,在真正的問題中我分裂了許多更多的領域) – Karl 2010-09-28 12:40:15

回答

2

很難做出了很多的建議。

我肯定會推薦的一件事是在JOIN條件中用作外鍵的那些列的索引,例如,

  • Age
  • dteEffectiveDate
  • dteNext

分別創建每個這些列的非聚集索引並再次測量。只有少數數據行,沒有什麼可衡量的改進 - 但是有數百萬行,這可能會有所不同。