对于简单的事情,最好使用translate
函数,前提是它的CPU密集度较低或者regexp_replace
的方法是什么?
这个问题来自How can I replace brackets to hyphens within Oracle REGEXP_REPLACE function?
答案 0 :(得分:10)
我认为你正在进行简单的优化。 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
on 11.2.0.3.0
:
regex :+000000000 00:00:00.617290000
translate :+000000000 00:00:00.138205000
结论:总的来说,我怀疑translate
会赢。
答案 1 :(得分:4)
对于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。