【发布时间】:2019-03-19 20:24:09
【问题描述】:
在我们的应用程序中,我们在会话级别配置了不区分大小写的语义:
alter session set NLS_COMP=LINGUISTIC;
alter session set NLS_SORT=BINARY_AI;
但是我想要一个具有二进制语义的 NAME 列的表,所以我相应地定义了一个基于函数的索引:
create table RAW_SCREEN (
ID number(10) constraint RSCR_PK primary key,
NAME nvarchar2(256) not null
);
create unique index RSCR_IDX on RAW_SCREEN (nlssort(NAME, 'NLS_SORT=BINARY'));
我希望下面的查询能够利用基于函数的索引:
select * from RAW_SCREEN where
nlssort(NAME, 'NLS_SORT=BINARY') = nlssort(N'raw_screen1', 'NLS_SORT=BINARY');
但事实并非如此。查询计划显示表扫描。在试验过程中,我发现 NAME 上的简单索引可以解决问题:
create unique index RSCR_IDX2 on RAW_SCREEN (NAME);
再次运行查询时,成功使用了 RSCR_IDX2 索引。
现在,这并不奇怪,但我不明白为什么优化器没有使用第一个基于函数的索引。索引表达式与 WHERE 条件中使用的表达式完全匹配。你知道为什么不使用它吗?
注意:这是在 Oracle 10.2 上运行的
如果您想尝试一下,这里有一个完整的测试脚本:
alter session set NLS_COMP=LINGUISTIC;
alter session set NLS_SORT=BINARY_AI;
create table RAW_SCREEN (
ID number(10) constraint RSCR_PK primary key,
NAME nvarchar2(256) not null
);
create unique index RSCR_IDX on RAW_SCREEN (nlssort(NAME, 'NLS_SORT=BINARY'));
--create unique index RSCR_IDX2 on RAW_SCREEN (NAME);
begin
for i in 1..10000
loop
insert into RAW_SCREEN values (i, 'raw_screen' || i);
end loop;
end;
/
commit;
select * from RAW_SCREEN where nlssort(NAME, 'NLS_SORT=BINARY') = nlssort(N'raw_screen1000', 'NLS_SORT=BINARY');
【问题讨论】:
标签: oracle