假设我有以下列
InsertedTime DateTime not null
ItemType tinyint not null
ItemType in {0, 1, 2, 3, 4, ... , 255}
我有一个查询,如果按InsertedTime
编入索引,它运行速度最快:where InsertedTime > Monday and InsertedTime < Tuesday
但是,我还希望在DateRange中按ItemType进行查询,让我们说ItemType == 0 and InsertedTime > Monday and InsertedTime < Tuesday
的所有行。
对于第一个查询,索引为{InsertedTime, ItemType}
是有意义的。但是,如果我将此索引用于第二个查询,则sql需要扫描整个日期范围结果。
要优化第二个查询,我会使用{ItemType, InsertedTime}
索引。但是使用这个索引,sql需要256个搜索第一个查询。
有没有办法使用单个索引优化两个查询?
答案 0 :(得分:0)
如果您希望通过&#34;星期一&#34;有效过滤,则会出现问题或&#34;星期二&#34;因为这些只能由datename(weekday,InsertedTime)
访问,并且您不能将其用作持久计算列,因为它是非确定性的&#34;因为它取决于语言设置等内容,甚至datepart(weekday,InsertedTime)
也会受到影响,因为它取决于firstday
设置。
要获得可持久的工作日(0 =星期一)的可靠整数表示,请尝试:
alter table Table1
add InsertedWeekday as (datediff(day,0,InsertedTime)%7) persisted;
如果确实需要,您也可以使用相同的逻辑创建一个案例表达式来获取日期名称标签。
然后可以将已拥有的计算列包括在索引中,例如
create index ixWeekdayType on Table1 (InsertedWeekday,ItemType);
这可能有助于这种查询方式:
select *
from Table1
where InsertedWeekday in (0,1) -- Monday/Tuesday
and ItemType between 20 and 30
不是我推荐它,但以下是&#34;确定性&#34;因此允许:
alter table Table1
add InsertedWeekdayName as (case datediff(day,0,InsertedTime)%7
when 0 then 'Monday'
when 1 then 'Tuesday'
when 2 then 'Wednesday'
when 3 then 'Thursday'
when 4 then 'Friday'
when 5 then 'Saturday'
when 6 then 'Sunday'
end
) persisted;