对于简单的事情之一是它更好地使用translate
功能的前提是,它不太CPU密集型或者是regexp_replace
要走的路?Oracle中regexp_replace与translate的性能?
这个问题来描述了从How can I replace brackets to hyphens within Oracle REGEXP_REPLACE function?
对于简单的事情之一是它更好地使用translate
功能的前提是,它不太CPU密集型或者是regexp_replace
要走的路?Oracle中regexp_replace与translate的性能?
这个问题来描述了从How can I replace brackets to hyphens within Oracle REGEXP_REPLACE function?
对于SQL,我用下面的脚本测试这一点:
set timing on
select sum(length(x)) from (
select translate('(<FIO>)', '()[]', '----') x
from (
select *
from dual
connect by level <= 2000000
)
);
select sum(length(x)) from (
select regexp_replace('[(<FIO>)]', '[\(\)\[]|\]', '-', 1, 0) x
from (
select *
from dual
connect by level <= 2000000
)
);
,发现translate
和regexp_replace
性能几乎都是一样的,但它可能因为其他操作的成本压倒了我试图测试的功能的成本。
接下来,我尝试了PL/SQL版本:
set timing on
declare
x varchar2(100);
begin
for i in 1..2500000 loop
x := translate('(<FIO>)', '()[]', '----');
end loop;
end;
/
declare
x varchar2(100);
begin
for i in 1..2500000 loop
x := regexp_replace('[(<FIO>)]', '[\(\)\[]|\]', '-', 1, 0);
end loop;
end;
/
这里translate
版只需不到10秒,而regexp_replace
版本各地0.2秒 - 大约2个数量级的速度更快
在此基础上,我会更经常使用的正则表达式中我的表现关键代码 - SQL和PL/SQL。
我想你遇到了简单的优化。 regexp表达式计算起来非常昂贵,以至于结果被缓存,希望将来会再次使用。如果您实际使用不同的字符串进行转换,您会发现适度的转换速度自然更快,因为它是它的专用功能。
这里是我的榜样,在11.1.0.7.0
运行:
SQL> DECLARE
2 TYPE t IS TABLE OF VARCHAR2(4000);
3 l t;
4 l_level NUMBER := 1000;
5 l_time TIMESTAMP;
6 l_char VARCHAR2(4000);
7 BEGIN
8 -- init
9 EXECUTE IMMEDIATE 'ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2';
10 SELECT dbms_random.STRING('p', 2000)
11 BULK COLLECT
12 INTO l FROM dual
13 CONNECT BY LEVEL <= l_level;
14 -- regex
15 l_time := systimestamp;
16 FOR i IN 1 .. l.count LOOP
17 l_char := regexp_replace(l(i), '[]()[]', '-', 1, 0);
18 END LOOP;
19 dbms_output.put_line('regex :' || (systimestamp - l_time));
20 -- tranlate
21 l_time := systimestamp;
22 FOR i IN 1 .. l.count LOOP
23 l_char := translate(l(i), '()[]', '----');
24 END LOOP;
25 dbms_output.put_line('translate :' || (systimestamp - l_time));
26 END;
27/
regex :+000000000 00:00:00.979305000
translate :+000000000 00:00:00.238773000
PL/SQL procedure successfully completed
上11.2.0.3.0
:
regex :+000000000 00:00:00.617290000
translate :+000000000 00:00:00.138205000
结论:总的来说,我怀疑translate
会获胜。
我想你跳转到一个结论有点仓促这里:)如果你想想看,只有缓存优化可以解释在运行时的差异如此巨大。在现实世界的例子中,你不会一遍又一遍地转换同一个字符串。 –
不过,有趣的是,在某些情况下,'regexp' **比'translate'更快** :) –
在10g上我发现REGEXP_可靠地比它们的非REGEXP类似物慢一到两个数量级(当做足够的东西来衡量差异)。然而,10g是第一个内置正则表达式函数的版本,我预计Oracle会为11g做一些重要的调整。 – APC