2017-09-13 32 views
0
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%' 

上述编码花费的时间太多。表格3非常庞大。 以上是动态的。任何替代品nvl?提高包含上层和nvl功能的查询的性能

回答

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

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

正常的索引无助,因为有两列正在播放。即使是基于函数的索引像这样...

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)));

如果使用数据库的旧版本,你必须建立一个正常的柱,并用触发器来填充它。

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

tab3是一个视图。如果我在这个视图上创建一个视图。 {作为org_name1从tab3创建视图tab3_vw作为选择org_name,上(NVL(org_name,company_given));}如果选择操作在这个视图上完成,这将提高性能。 – user3165555

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将避免,如果第一部分已经是false

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