PL/SQL 开发人员 - Oracle10g
我有一个查询在使用 LIKE 运算符设置时丢失索引,但仅使用前缀“%”
例如:
select * from people where name like '%POTATO'
其在优化器目标表中返回“访问完整”。 如何获得轮廓解决方案?
如果您认为通过这样一个特殊的名称结尾进行查询真的很重要,请考虑创建一个
function-based
索引:
create index idx_special_people
on people(upper(substr(name,-6)));
收集表统计数据:
exec dbms_stats.gather_table_stats(user, 'people', cascade => true);
并致电:
select *
from people
where upper(substr(name,-6)) = 'POTATO'
优化器会采用多种方法,包括全表扫描和索引全扫描。想必它的计算表明全表扫描会更高效。这很可能是因为您必须完全扫描整个索引才能找到以“POTATO”结尾的键,而以“POTATO”开头的键存储在一起(就像在电话簿中一样)。
如果您分享表和索引的详细信息、数据量和执行计划,有人可能能够提供更详细的建议。
您可以尝试使用提示:
select /*+ INDEX(people indexname) */ * from people where name like '%POTATO'
编辑:前几天我再次面临这个问题,并提出了另一个解决方案。 Oracle 支持基于函数的索引,并且 Oracle 还可以使用
%
作为后缀而不是前缀。
我的解决方案是使用基于函数的索引和
reverse
子句。因此,我不是将 name
与 '%POTATO'
匹配,而是将 name
的反向与 '%POTATO'
的反向匹配,例如:
select * from people where reverse(name) like reverse('%POTATO')
我检查了变量的第一个字符,所以它更像是:
select * from people
where substr('%POTATO', 1, 1) = '%' and reverse(name) like reverse('%POTATO')
or substr('%POTATO', 1, 1) != '%' and name like '%POTATO'
与 INDEX 结合使用,例如:
create index people.idx02_on_people
on SCHEMA.people (reverse(name))
tablespace YOUR_TABLESPACE