2

こんにちは、みんな

定期的に実行しなければならないクエリを改善するのを誰かが手伝ってくれることを望んでいました。現時点では、実行に 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 のレコードである実際のデータに対してこれを実行すると、実行に非常に時間がかかります。

誰か提案はありますか?

ありがとう
カール

4

1 に答える 1

2

多くの推奨事項を作成することは困難です。

私が絶対にお勧めしたいことの 1 つは、JOIN 条件で外部キーとして使用する列のインデックスです。

  • Age
  • dteEffectiveDate
  • dteNext

それらの各列に個別に NONCLUSTERED インデックスを作成し、再度測定します。ほんの数行のデータでは測定可能な改善はありませんが、数百万行の場合は違いが生じる可能性があります.

于 2010-09-28T12:50:34.267 に答える