我有一张包含数百万条目的表格。三个字段city
,street
和name
也有一些索引。
但是当我执行以下查询时,返回任何结果需要10秒+。
SELECT bd.*
FROM BASEDATA bd
WHERE 1=1
AND lower(city) LIKE '%city%'
AND lower(street) LIKE '%street%'
AND lower(name) LIKE '%schmidt%'
查看解释计划时,它显示查询是使用全表扫描而不是使用索引执行的。
答案 0 :(得分:5)
索引基本上以字母数字顺序组织值。给定一个谓词,它从值的前沿开始查找索引。因此,对于key = 'ABC'
,它会转到索引的一部分,其值以A
开头并从那里搜索。
现在我们查看您的查询,我们发现WHERE子句中没有任何谓词具有前导值。 lower(city) LIKE '%city%'
可以完全匹配aaa city
到zzz city
之间的任何内容。所以可能是表中的每条记录。索引在这种情况下是无用的,全表扫描更有效。
(顺便说一句,将函数应用于列,如lower(city)
中也会阻止使用索引,除非您在该列上有适当的基于函数的索引。)
如果您想进行大量此类查询,则应调查Oracle的Text功能。它使用特殊索引来支持contains()
等自由文本运算符。这些索引存在开销,因此您需要了解将获得哪些好处。 Find out more。