查询内部范围

时间:2017-10-27 20:31:55

标签: sql sql-server indexing

假设我有以下列

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个搜索第一个查询。

有没有办法使用单个索引优化两个查询?

1 个答案:

答案 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;