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的任何替代方案?
答案 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%'
如果这是一次性练习,我建议你花点时间等待声明完成。但是我们假设您经常要进行此类查询。如果是这样,那么建立基础设施来支持它是值得的。
搜索条件的新列。基本上是一个预先填充了函数中使用的参数的列。对于11g或更高版本,请将其设为虚拟列:
alter table tab3 add search_name as ( upper(NVL(org_name, company_given)));
如果使用较旧版本的数据库,则必须构建一个普通列并使用触发器填充它。
search_name
列上构建文本索引。由于它很短,您可以使用CTXCAT索引,该索引将以交易方式维护。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%'))
如果找不到SOFT
或APP
,则无需检查包含相同字词的其他字词 - and
如果第一部分已经{{1}将避免}}
如果这只是一个示例,并且这些参数是可变的,您可以编写一些代码来优化这些搜索项(除非SQL服务器已经这样做了)。