0

構造を持つテーブルが 1 つあります。

 CREATE TABLE [dbo].[rx](
            [pat_id] [int] NOT NULL,
            [fill_Date] [date] NOT NULL,
            [script_End_Date]  AS (dateadd(day,[dayssup],[filldate])),
            [drug_Name] [varchar](50) NULL,
            [days_Sup] [int] NOT NULL,
            [quantity] [float] NOT NULL,
            [drug_Class] [char](3) NOT  NULL,
            [ofInterest] bit
            CHECK(fill_Date <=script_End_Date
PRIMARY KEY CLUSTERED 
(
            [clmid] ASC
)


CREATE TABLE [dbo].[Calendar](
             [cal_date] [date] PRIMARY KEY,
[Year] AS YEAR(cal_date) PERSISTED,
[Month] AS MONTH(cal_date) PERSISTED,
[Day] AS DAY(cal_date) PERSISTED,
             [julian_seq] AS 1+DATEDIFF(DD, CONVERT(DATE, CONVERT(varchar,YEAR(cal_date))+'0101'),cal_date),
     id int identity);

このクエリでこれらのテーブルを使用しました。

;WITH x 
     AS (SELECT rx.pat_id, 
                c.cal_date, 
                Count(DISTINCT rx.drug_name) AS distinctDrugs 
         FROM   rx, 
                calendar AS c 
         WHERE  c.cal_date BETWEEN rx.fill_date AND rx.script_end_date 
                AND rx.ofinterest = 1 
         GROUP  BY rx.pat_id, 
                   c.cal_date 
         --the query example I used having count(1) =2, but to illustrate the non-contiguous intervals, in practice I need the below having statement
         HAVING Count(*) > 1), 
     y 
     AS (SELECT x.pat_id, 
                x.cal_date 
                --c2.id is the row number in the calendar table. 
                , 
                c2.id - Row_number() 
                          OVER( 
                            partition BY x.pat_id 
                            ORDER BY x.cal_date) AS grp_nbr, 
                distinctdrugs 
         FROM   x, 
                calendar AS c2 
         WHERE  c2.cal_date = x.cal_date) 
SELECT *, 
       Rank() 
         OVER( 
           partition BY pat_id, grp_nbr 
           ORDER BY distinctdrugs) AS [ranking] 
FROM   y 

calendar テーブルは 3 年間実行され、rx テーブルには約 800,000 行あります。前述のクエリを数分間実行した後、処理を高速化するためにインデックスを追加することにしました。追加したインデックスは

create index ix_rx
on rx (clmid)
include (pat_id,fill_date,script_end_date,ofinterest)

このインデックスは、クエリの実行時間にまったく影響を与えませんでした。前述のインデックスが使用されていない理由を説明できる人はいますか? これはレトロスペクティブ データベースであり、これ以上データが追加されることはありません。必要に応じて実行計画を追加できます。

4

2 に答える 2

2

このclmidフィールドは、クエリではまったく使用されません。そのため、インクルード列についてのみ、オプティマイザーがそれを考慮した場合、私は驚くでしょう。

インデックスを使用してクエリを高速化したい場合は、テーブルが使用されているクエリから始めます。使用されるフィールドはpat_id、、、、、およびです。最後の 2 つは、その間にあるためやりがいがあります。このインデックスを試すことができます: .drug_namerx_ofinterestfill_datescript_end_daterx(pat_id, drug_name, ofinterest, fill_date, script_end_date)

インデックスにすべての参照フィールドがあると、データ ページをロードせずにデータにアクセスできるようになります。

于 2013-01-31T19:19:51.767 に答える
0

適切な指標ではないからです。[pat_id] に 1 つ、drug_name にもう 1 つの 2 つのインデックスを作成します。–</p>

于 2013-01-31T19:20:29.243 に答える