如何加快查询中的子搜索速度

时间:2012-04-19 19:38:43

标签: oracle substr substring

我使用它作为子选择(在一个简单的查询中连接其他2个表),你可以想象它需要一段时间才能运行。到目前为止6个小时+ 这是唯一的方法吗?我知道做另一个JOIN而不是子选择可能会有所帮助。但主要的瓶颈是所有这些OR和子串。

SELECT ex_array
FROM   service_x 
WHERE  
   ( substr(ex_array,1,2) = 'FW' OR substr(ex_array,3,2) = 'FW' OR substr(ex_array,5,2) = 'FW' OR substr(ex_array,7,2) = 'FW' OR substr(ex_array,9,2) = 'FW' OR substr(ex_array,11,2) = 'FW' ) 
OR ( substr(ex_array,1,2) = 'IL' OR substr(ex_array,3,2) = 'IL' OR substr(ex_array,5,2) = 'IL' OR substr(ex_array,7,2) = 'IL' OR substr(ex_array,9,2) = 'IL' OR substr(ex_array,11,2) = 'IL' )  
OR ( substr(ex_array,1,2) = 'IN' OR substr(ex_array,3,2) = 'IN' OR substr(ex_array,5,2) = 'IN' OR substr(ex_array,7,2) = 'IN' OR substr(ex_array,9,2) = 'IN' OR substr(ex_array,11,2) = 'IN' )  
OR ( substr(ex_array,1,2) = 'IK' OR substr(ex_array,3,2) = 'IK' OR substr(ex_array,5,2) = 'IK' OR substr(ex_array,7,2) = 'IK' OR substr(ex_array,9,2) = 'IK' OR substr(ex_array,11,2) = 'IK' )  
OR ( substr(ex_array,1,2) = 'IH' OR substr(ex_array,3,2) = 'IH' OR substr(ex_array,5,2) = 'IH' OR substr(ex_array,7,2) = 'IH' OR substr(ex_array,9,2) = 'IH' OR substr(ex_array,11,2) = 'IH' )  
OR ( substr(ex_array,1,2) = 'KP' OR substr(ex_array,3,2) = 'KP' OR substr(ex_array,5,2) = 'KP' OR substr(ex_array,7,2) = 'KP' OR substr(ex_array,9,2) = 'KP' OR substr(ex_array,11,2) = 'KP' )  
)

4 个答案:

答案 0 :(得分:3)

您可以尝试使用function based index。具体来说,在substr(ex_array,3,2)和substr(ex_array,9,2)等上创建基于函数的索引。

虽然可能有很多索引,所以你必须通过运行一些测试来衡量它有多大帮助。但这是一个开始的想法。

我假设你是8i或更晚。

答案 1 :(得分:1)

这个结构怎么样......

INSTR( ex_array, 'FW' ) IN (1,3,5,7,9,11)

然后至少你只会进行一次字符串解析...

答案 2 :(得分:1)

也许使用regexp_like

REGEXP_LIKE(ex_array, '^(.{2}){0,5}(FW|IL|IN|IK|IH|KP).*$')

(正则表达式可能写得更好......)

您还可以添加基于函数的索引 dcp 建议(尽管您只需要一个):

create index fbIndex on service_x (REGEXP_INSTR(ex_array, '^(.{2}){0,5}(FW|IL|IN|IK|IH|KP).*$'));

并更改要使用的查询:

REGEXP_INSTR(ex_array, '^(.{2}){0,5}(FW|IL|IN|IK|IH|KP).*$') = 1

答案 3 :(得分:0)

鉴于您需要的查询的选择性,我建议给出可用的信息:

1)ex_array上的索引(最好只是ex_array,或者在索引的前沿使用ex_array。

2)修改查询。如果您附加其他过滤条件:

... 和(Ex_array喜欢'%FW%'或ex_array喜欢'%IL%'或ex_aray喜欢...... Etc涵盖了六个案例中的每一个。随着索引到位,这应该使索引范围扫描能够减少1220万行只包含那些包含您感兴趣的六个字符串之一的行。只有这些行将应用您的substr逻辑,留下预期的175K。

原则上,这应该提高效率。它确实在很大程度上依赖于数据分布(例如,所有1200万行可能包含六个字符串中的一个,而不是在原始查询中指定的位置。在这种情况下,我建议的更改可能效率低于原始查询查询)。可能还有其他选择,但我需要更多信息,包括更准确的解释计划。

希望这会有所帮助 - 祝你好运!