Oracle在'%test%query中执行全表扫描

Chr*_*ipp 0 sql oracle sql-like

我有一张表,里面有数百万个条目.这三个领域也有一些指数city,streetname.

但是当我执行以下查询时,返回任何结果需要10秒+.

SELECT bd.*
FROM BASEDATA bd 
WHERE 1=1 
AND lower(city) LIKE '%city%' 
AND lower(street) LIKE '%street%' 
AND lower(name) LIKE '%schmidt%' 
Run Code Online (Sandbox Code Playgroud)

查看解释计划时,它显示使用全表扫描而不是使用索引执行查询.

APC*_*APC 5

基本上,索引以字母数字顺序组织值.给定一个谓词,它从值的前沿开始查找索引.因此,key = 'ABC'它会转到索引的一部分,其值A从那里开始并从那里搜索.

现在我们查看您的查询,我们发现WHERE子句中没有任何谓词具有前导值.lower(city) LIKE '%city%'可以从字面上匹配来自任何东西aaa cityzzz city.所以可能是表中的每条记录.在这种情况下,索引是无用的,并且全表扫描更有效.

(顺便说一句,将函数应用于列,如同lower(city)也会阻止使用索引,除非您在该列上具有适当的基于函数的索引.)

如果您想进行大量此类查询,则应调查Oracle的Text功能.它使用特殊索引来支持自由文本操作符contains().这些索引存在开销,因此您需要了解将获得哪些好处.了解更多.