SQL:按附加索引进行可选搜索

时间:2018-06-26 12:26:56

标签: sql sql-server

我有一张桌子,上面有一些数据,包括日期:

id   action_type     created_date    data
1     action 1      20180405 03:00    ...
2     action 2      20180405 03:01    ...
3     action 1      20180405 02:58    ...

我有两个单独的索引(我无法添加另一个索引):action_typecreated_date。我需要一个查询,该查询将选择在某些日期之间具有某些action_type的所有条目:

-- Query 1:
declare @from_date datetime = '20180101 00:00'
        ,@to_date datetime = '20180301 00:00'
        ,@action_type varchar(20) = 'action 1'

select  *
from    my_table
where   created_at between @from_date and @to_date
        and action_type = @action_type

我正在使用此查询,只是在声明部分中更改变量值。问题是我没有同时包含日期和类型的索引,因此查询效率不高,但是我对此无能为力。

但是,有时我需要为所有日期运行查询(没有日期限制)。我不想编写其他查询,所以我正在设置@from_date = '20010101 00:00'@to_date = getdate(),因为我确定所有日期都大于2001年1月1日。

我的问题是:

1我想服务器无法“理解”所有数据都在该区域内,并且仍按日期执行搜索。我说对了,在这种情况下,不按日期运行搜索会更有效,例如:

select  *
from    my_table
where   action_type = @action_type

2如果@from_date为空,以下查询是否会按日期消除搜索?我的意思是,对于不需要按日期约束的情况,这比查询1更有效吗?

select  *
from    my_table
where   (created_at between @from_date and @to_date or @from_date is null)
        and action_type = @action_type

3还有没有其他写两种情况的查询方式:如果不为null,则按日期搜索;如果为null,则按日期搜索;如果不为null,则按日期搜索。会有效吗?

1 个答案:

答案 0 :(得分:0)

我认为您可以使用union all

select t.*
from my_table t
where t.action_type = @action_type and @from_date is null
union all
select t.*
from my_table t
where t.action_type = @action_type and
      created_at >= @from_date and created_at <= @to_date is null;

每个子查询应独立评估。我认为SQL Server足够聪明,可以识别出NULL条件意味着没有行返回。