我有一个表ATable
,其中有一个在a
和b
上创建的索引。
我知道a
和b
中的所有值都以大写形式存储。
我怀疑索引在这种情况下表现正常
select
*
from
BTable b
join
ATable a on upper(b.a) = a.a and upper(b.b) = a.b;
但是如果我做一个选择
会怎样?select
*
from
BTable b
join
ATable a on upper(b.a) = upper(a.a) and upper(b.b) = upper(a.b);
将使用我的索引吗?还是我需要在ATable(upper(a), upper(b))
上创建索引?
排序规则是:
select DATABASEPROPERTYEX('MyDB','Collation');
-----
SQL_Latin1_General_CP1_CI_AS
答案 0 :(得分:2)
不,您不需要大写索引。
由于您使用的是不区分大小写的排序规则,因此查询中也不需要upper
,并且正如Sean Lange所述,upper
函数可以使该查询{{3} }(以下示例中没有)。如果删除upper
并且在这些列上有索引,则可以使用它。我说可以,因为您正在做select *
,所以优化器可以选择表扫描,因为您需要所有列。
为了进一步说明,由于排序规则不区分大小写,abc
与AbC
相同,因此无论是否使用upper
函数,都将返回相同的结果,但是性能之所以不一样,是因为:
upper
函数本身需要时间和资源才能运行您可以通过选中nonSARGable来查看此操作。您会看到该功能很痛苦!
这是代码,以及该链接中的执行计划图片
create table #t1(c1 varchar(8) not null)
alter table #t1 add constraint t1_PK primary key (c1)
create table #t2(c1 varchar(8) not null)
alter table #t2 add constraint t2_PK primary key (c1)
insert into #t1
values
('aaa'),
('BBB'),
('ccc'),
('DDD')
insert into #t2
values
('AAA'),
('bbb'),
('Ccc'),
('dDD')
select *
from #t1 t1
inner join #t2 t2
on t1.c1 = t2.c1
select *
from #t1 t1
inner join #t2 t2
on upper(t1.c1) = upper(t2.c1)
drop table #t1
drop table #t2