LIKE'%...%'通配符查询的PL/SQL性能调优

Гро*_*ный 15 sql oracle indexing query-optimization

我们正在使用Oracle 11g数据库.
正如你可能会或可能不知道,如果你在前面的字符串使用通配符查询用"%",列没有被使用的索引全表扫描正在发生的事情.

看起来似乎没有关于如何改进此类查询的明确建议,但也许您可以根据您的经验分享一些有价值的信息,以了解如何优化以下查询:

SELECT * 
  FROM myTable 
 WHERE UPPER(CustomerName) like '%ABC%' 
    OR UPPER(IndemnifierOneName) like '%ABC%' 
    OR UPPER(IndemnifierTwoName) like '%ABC%';
Run Code Online (Sandbox Code Playgroud)

...其中所有3列的类型为varchar2(100),ABC是变量输入参数的值.

@All建议使用CONTEX索引,请注意我的数据每天的任何时间都会更新,而且这个索引需要重新同步,因此对于150万行的表来说这不是一个好的选择,抱歉.

PS我会支持每个答案,所以请保持他们的到来.

Kev*_*ton 7

如前所述,您可以向名称列添加ctx上下文索引.

假设有少量记录得到更新,1个选项是每天刷新索引.(并在发生时记录)

然后将lastupdate日期列和索引添加到正在搜索的表中.

应该可以扫描ctx索引中的大多数旧的未更改数据,并使用传统LIKE从较小百分比的更新数据中进行选择,例如:

WHERE (lastupdated<lastrefresh AND contains(name,'%ABC%')) 
   OR (lastupdated>lastrefresh AND name like '%ABC%')
Run Code Online (Sandbox Code Playgroud)

注意:您可能会发现您的查询计划有点精神错乱(许多位图转换为行ID),在这种情况下,将OR的2部分拆分为UNION ALL查询.例如

SELECT id FROM mytable   
    WHERE 
    (lastupdate>lastrefresh and name LIKE '%ABC%')
    UNION ALL
    SELECT id FROM mytable   
    WHERE lastupdate<lastrefresh and CONTAINS(name, '%ABC%', 1) > 0
Run Code Online (Sandbox Code Playgroud)


Fos*_*sco 6

唯一的优化是不使用该类型的查询,而是使用数据库平台的本机功能:

请参阅Oracle Text:http://www.oracle.com/technetwork/database/enterprise-edition/index-098492.html

SQL Server相关问题的常见答案是全文搜索.很高兴看到Oracle有一些好或更好的东西.