提高包含upper和nvl fucntion的查询的性能

时间:2017-09-13 06:59:33

标签: sql oracle performance query-optimization sql-insert

INSERT INTO tab2 NOLOGGING
SELECT 
   ID,
  ORG_NAME
FROM tab3
WHERE (( upper(NVL(org_name,company_given)) LIKE '%MSOFT%'
OR upper(NVL(org_name,company_given)) LIKE 'M SOFT'
OR upper(NVL(org_name,company_given)) LIKE '%MISOFT%'
OR upper(NVL(org_name,company_given)) LIKE 'MSN %'
OR upper(NVL(org_name,company_given)) LIKE '%N APP%'
OR upper(NVL(org_name,company_given)) LIKE '%NAPP%'
OR upper(NVL(org_name,company_given)) LIKE '%NAPPE%'
OR upper(NVL(org_name,company_given)) LIKE '%NAPPS%'
OR upper(NVL(org_name,company_given)) LIKE '%NEK%APPLIANCE%'

以上编码花费了太多时间。表tab3非常庞大。 以上是动态的。 nvl的任何替代方案?

3 个答案:

答案 0 :(得分:1)

以下一行

OR upper(NVL(org_name,company_given)) LIKE 'M SOFT'

可以替换为

OR ((orgname is not null  and upper(org_name) LIKE 'M SOFT')
    OR ((orgname is null  and upper(company_given) LIKE 'M SOFT')

不确定它的速度更快。

您也可以尝试使用子查询

运行一次
SELECT *
FROM (
    SELECT 
       ID,
       ORG_NAME,
       upper(NVL(org_name,company_given)) as name_for_filter
    FROM tab3)
WHERE name_for_filter LIKE '%MSOFT%'
  OR name_for_filter LIKE 'M SOFT'
...

最好的方法是在表格中引入name_for_filter列,并使用触发器填充一次。然后该列可用于过滤

答案 1 :(得分:1)

此查询将执行表的全表扫描。你说桌子很大,所以需要很长时间。

普通索引无济于事,因为有两列正在播放。甚至像这样的基于函数的索引......

create index fbi3 on tab3( upper(NVL(org_name, company_given) ))

...无济于事,因为索引对前面带有通配符的like过滤器无用,你有:

LIKE '%NEK%APPLIANCE%'

如果这是一次性练习,我建议你花点时间等待声明完成。但是我们假设您经常要进行此类查询。如果是这样,那么建立基础设施来支持它是值得的。

  1. 搜索条件的新列。基本上是一个预先填充了函数中使用的参数的列。对于11g或更高版本,请将其设为虚拟列:

    alter table tab3 add search_name as ( upper(NVL(org_name, company_given)));

  2. 如果使用较旧版本的数据库,则必须构建一个普通列并使用触发器填充它。

    1. search_name列上构建文本索引。由于它很短,您可以使用CTXCAT索引,该索引将以交易方式维护。
    2. 然后,您需要重写查询以使用catsearch()语法而不是like运算符。 Find out more

答案 2 :(得分:0)

正如已经建议的那样,最好是创建一个准备好的搜索列。您甚至可以删除空格以避免搜索'N APP''NAPP'(例如,在某些情况下可能会导致误报)。

最重要的是,您可以删除对%NAPPE%%NAPPS%的检查,因为您已经包含了包含%NAPP%的记录

使用时应该更快:

pseudocode:

   'MSN %'
or ('%SOFT%' and ('M SOFT' or '%MSOFT%' or '%MISOFT%'))
or ('%APP%' and ('%N APP%' or '%NAPP%' or '%NEK%APPLIANCE%'))

如果找不到SOFTAPP,则无需检查包含相同字词的其他字词 - and如果第一部分已经{{1}将避免}}

如果这只是一个示例,并且这些参数是可变的,您可以编写一些代码来优化这些搜索项(除非SQL服务器已经这样做了)。