2013-04-17 26 views

cevap

4

dan ileri geliyor, ben şu komut dosyası ile bu test:

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 
) 
); 

ve translate ve regexp_replace performansı hemen hemen her zaman aynı olduğunu gördük, ama olabilir Diğer operasyonların maliyeti test etmeye çalıştığım fonksiyonların maliyetini ezmek olabilir. etrafında 0,2 saniye süre regexp_replace versiyonu Burada

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 sürümü sadece 10 saniyenin altında sürer - hızlı büyüklük yaklaşık 2 siparişler

:

Sonraki, bir PL/SQL versiyonunu denedik (!)

Bu sonuca dayanarak, performans kritik kodumda daha sık düzenli ifadeler kullanacağım - SQL ve PL/SQL.

+3

Burada biraz aceleyle atlattığınızı düşünüyorum. :) Bunu düşünürseniz, yalnızca önbellek optimizasyonu çalışma zamanındaki bu büyüklük farkını açıklayabilir. Gerçek bir dünya örneğinde, aynı dizgeyi şüphelendiğim yere çeviremezsiniz. –

+2

Yine de bazı durumlarda 'regexp' **' translate'den daha hızlı ** olduğunu görmek ilginçtir :) –

+0

10g üzerinde REGEXP_'in REGEXP olmayan analoglarından daha yavaş bir ya da iki derece güvenilir olduğunu buluyorum. Farkı ölçmek için bir şeyler yapmak yeterlidir). Ancak, 10g yerleşik regex işlevleri ile ilk sürümüdür ve Oracle'ın 11g için bazı önemli ayarlamalar yapmasını beklerdim. – APC

10

Sanırım basit bir optimizasyon yapıyorsunuz. Regexp ifadesi, sonucun gelecekte tekrar kullanılacağı umuduyla önbelleğe alındığını hesaplamak için çok pahalıdır. Gerçekten dönüştürmek için farklı dizeler kullanırsanız, mütevazı çevirmenin doğal olarak daha hızlı olduğunu göreceksiniz çünkü özel işlevi.

İşte 11.1.0.7.0 üzerinde çalışan, benim örnek:

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 tarih:

regex  :+000000000 00:00:00.617290000 
translate :+000000000 00:00:00.138205000 

Sonuç: Genel olarak ben translate kazanacak şüpheli.