對於簡單的事情之一是它更好地使用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