こんにちは、みんな
定期的に実行しなければならないクエリを改善するのを誰かが手伝ってくれることを望んでいました。現時点では、実行に 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 があり、最も近い前/次の発効日の日付が反映されます。今私が欲しいのは、特定の年齢内の連続する期間の間の Count フィールドの中間値を計算するクエリです。
たとえば、上記のデータでは、40 歳の場合、2009/01/01 では 300、2010/01/01 では 200 であるため、クエリは 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
完全に機能しますが、約 7m のレコードである実際のデータに対してこれを実行すると、実行に非常に時間がかかります。
誰か提案はありますか?
ありがとう
カール