我使用它作为子选择(在一个简单的查询中连接其他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' )
)
答案 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万行可能包含六个字符串中的一个,而不是在原始查询中指定的位置。在这种情况下,我建议的更改可能效率低于原始查询查询)。可能还有其他选择,但我需要更多信息,包括更准确的解释计划。
希望这会有所帮助 - 祝你好运!