我有一个结构表:
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
日历表运行三年,rx表中有大约800k行。在前面的查询运行了几分钟后,我决定为它添加一个索引以加快速度。我添加的索引是
create index ix_rx
on rx (clmid)
include (pat_id,fill_date,script_end_date,ofinterest)
此索引对查询的运行时间没有任何影响。任何人都可以帮助解释为什么没有使用上述索引?这是一个回顾性数据库,不再添加任何数据。如果需要,我可以添加执行计划。
答案 0 :(得分:2)
查询中根本没有使用clmid
字段。因此,如果优化器会考虑它,我会感到惊讶,只是对于包含列。
如果要使用索引加速查询,请从使用该表的查询开始。使用的字段为pat_id
,drug_name
,rx_ofinterest
,fill_date
和script_end_date
。最后两个因为中间因素而具有挑战性。您可以尝试使用此索引:rx(pat_id, drug_name, ofinterest, fill_date, script_end_date)
。
索引中包含所有引用的字段,可以在不加载数据页的情况下访问数据。
答案 1 :(得分:0)
因为它不是合适的索引。在[pat_id]上创建两个索引,在drug_name上创建另一个索引。 -