您正在使用会因此它不会大规模随着表的增长做全表扫描去的方法。如果您想要实现更高效的解决方案(不使用Oracle大型文本索引)并使用索引,请使用基于函数的索引来预先计算列常用的子字符串。
使用INSTR()可以发现列是否是另一列的子字符串,并返回一个分数。 0表示不匹配。
create index ix_t_score on t (instr(nvl(column_1,' '), nvl(column_2, ' ')),
instr(nvl(column_2,' '), nvl(column_1, ' ')));
现在编写查询,使其允许Oracle使用索引。
-- Find rows that don't have common strings
select * from t
where instr(nvl(column_1, ' '), nvl(column_2, ' ')) = 0 and
instr(nvl(column_2, ' '), nvl(column_1, ' ')) = 0;
-- Find rows that do
select * from t
where instr(nvl(column_1, ' '), nvl(column_2, ' ')) > 0 or
instr(nvl(column_2, ' '), nvl(column_1, ' ')) > 0;
set autotrace on
Execution Plan
----------------------------------------------------------
Plan hash value: 4100696360
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 22 | | |
|* 2 | INDEX RANGE SCAN| IX_T_SCORE | 1 | 22 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(INSTR(NVL("COLUMN_1",' '),NVL("COLUMN_2",' '))=0 AND
INSTR(NVL("COLUMN_2",' '),NVL("COLUMN_1",' '))=0)
您可以通过创建确定性存储过程/函数来返回分数来简化它,并且SQL变得比上述简单得多。 NVL()的使用是用零值来处理列。