간단하게 말해서 CPU 사용량이 적거나 이동 방법이 regexp_replace
이라는 전제하에 translate
함수를 사용하는 것이 더 낫습니다.regexp_replace의 성능 대 Oracle의 번역?
이 문제는 SQL의 How can I replace brackets to hyphens within Oracle REGEXP_REPLACE function?
간단하게 말해서 CPU 사용량이 적거나 이동 방법이 regexp_replace
이라는 전제하에 translate
함수를 사용하는 것이 더 낫습니다.regexp_replace의 성능 대 Oracle의 번역?
이 문제는 SQL의 How can I replace brackets to hyphens within Oracle REGEXP_REPLACE function?
에서 앞으로 온다, 나는 다음과 같은 스크립트를 사용하여이 테스트 :
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
의 성능이 거의 항상 같은 사실을 발견하지만, 수 다른 작업의 비용이 내가 테스트하려고하는 기능의 비용을 압도하고 있는지 확인하십시오. 약 0.2 초 동안 regexp_replace
버전, 여기에
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 초 미만 소요 - 빠른 크기의 약 2 주문
다음으로, 나는 PL/SQL 버전을 시도 (!)
이 결과를 토대로 성능 핵심 코드 (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가 아닌 아날로그보다 1 ~ 2 배 더 느린 것으로 나타났습니다 (그 차이를 측정하기에 충분한 것). 그러나 10g는 정규식 기능이 내장 된 첫 번째 릴리스였으며 오라클이 11g에 대해 중요한 튜닝을 수행 할 것으로 기대했을 것입니다. – APC