Oracle在类似'%test%查询中执行全表扫描

时间:2017-02-22 08:08:28

标签: sql oracle sql-like

我有一张包含数百万条目的表格。三个字段citystreetname也有一些索引。

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

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

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

1 个答案:

答案 0 :(得分:5)

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

现在我们查看您的查询,我们发现WHERE子句中没有任何谓词具有前导值。 lower(city) LIKE '%city%'可以完全匹配aaa cityzzz city之间的任何内容。所以可能是表中的每条记录。索引在这种情况下是无用的,全表扫描更有效。

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

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