sql >> データベース >  >> RDS >> Oracle

Oracleでは、コンマで区切られた非常に大きな文字列(clob)をより良いパフォーマンスでテーブルに変換することは可能ですか?

    通常のinstr/substrの代わりにDBMS_LOBを使用すると、これを1桁高速化できます。

    CREATE OR REPLACE FUNCTION DROPME$STRSPLIT2 (
       P_STR     IN CLOB,
       P_DELIM   IN VARCHAR2 DEFAULT ';' ,
       P_LIKE    IN INT DEFAULT 0
    )
       RETURN SYS.ODCIVARCHAR2LIST
    AS
      L_DATA SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST ();
      L_STR  CLOB := P_STR || P_DELIM;  
      L_SUBSTR VARCHAR2(4000);
      L_STEP PLS_INTEGER := 0;
      L_THIS INT := 1;
      L_PREV INT := 0;
      L_END CHAR := CASE P_LIKE WHEN 0 THEN NULL ELSE '%' END;
    BEGIN  
      LOOP
        L_STEP := L_STEP + 1;
        L_THIS := DBMS_LOB.INSTR(L_STR, P_DELIM, L_PREV + 1, 1);    
        EXIT WHEN L_THIS = 0;
        L_SUBSTR := 
        TRIM(
          DBMS_LOB.SUBSTR(
            L_STR, 
            L_THIS - L_PREV - 1,
            L_PREV + 1
          )
        );        
        L_PREV := L_THIS;    
        L_DATA.EXTEND();
        L_DATA(L_STEP) := L_SUBSTR || L_END;
      END LOOP;
      RETURN L_DATA;
    END;
    

    テストケース、60kb CLOBを10回処理:

    あなたの職務:

    18:15:50 SQL> l
      1  DECLARE
      2    VAL CLOB;
      3    RESULT SYS.ODCIVARCHAR2LIST;
      4  BEGIN
      5    SELECT C INTO VAL FROM DROPME$C;
      6    FOR I IN 1 .. 10 LOOP
      7      RESULT := DROPME$STRSPLIT1(VAL);
      8    END LOOP;
      9* END;
    18:15:54 SQL> /
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:11.56
    

    アップグレードされた機能:

    18:17:12 SQL> l
      1  DECLARE
      2    VAL CLOB;
      3    RESULT SYS.ODCIVARCHAR2LIST;
      4  BEGIN
      5    SELECT C INTO VAL FROM DROPME$C;
      6    FOR I IN 1 .. 10 LOOP
      7      RESULT := DROPME$STRSPLIT2(VAL);
      8    END LOOP;
      9* END;
    18:17:14 SQL> /
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.87
    

    更新それらが同じ出力を提供することを確認するには:

    18:20:08 SQL> l
      1  SELECT * FROM TABLE(
      2    DROPME$STRSPLIT1('a;b;c;d;f')
      3* )
    18:20:10 SQL> /
    
    COLUMN_VALUE
    ------------
    a
    b
    c
    d
    f
    

    アップグレード

    18:20:16 SQL> l
      1  SELECT * FROM TABLE(
      2    DROPME$STRSPLIT2('a;b;c;d;f')
      3* )
    18:20:20 SQL> /
    
    COLUMN_VALUE
    ------------
    a
    b
    c
    d
    f
    


    1. PDO ::ATTR_EMULATE_PREPARESを無効にすると、「不明」の問題が発生します

    2. MySQLクエリのみを使用して重複を削除しますか?

    3. CSVを解析し、GrailsのMysqlデータベースにエクスポートします

    4. MySQL移動平均計算