“固定长度记录”和“固定长度字段”如何提高数据库性能?

时间:2013-01-26 15:29:16

标签: oracle oracle11g external-tables

任何人都可以通过ORACLE_LOADER访问驱动程序解释以下两个使用Oracle外部表性能改进的声明:

  1. 固定长度记录的处理速度比终止记录的速度快 一个字符串。
  2. 固定长度字段的处理速度快于分隔字段。
  3. 用代码解释可能有助于我深入理解这个概念。这是两个语法:

    固定字段长度

    create table ext_table_fixed (
       field_1 char(4),
       field_2 char(30)
    )
    organization external (
       type       oracle_loader
       default directory ext_dir
       access parameters (
         records delimited by newline
         fields (
           field_1 position(1: 4) char( 4),
           field_2 position(5:30) char(30)
        )
      )
      location ('file')
    )
    reject limit unlimited;
    

    逗号分隔

    create table ext_table_csv (
      i   Number,
      n   Varchar2(20),
      m   Varchar2(20)
    )
    organization external (
      type              oracle_loader
      default directory ext_dir
      access parameters (
        records delimited  by newline
        fields  terminated by ','
        missing field values are null
      )
      location ('file.csv')
    )
    reject limit unlimited;
    

2 个答案:

答案 0 :(得分:4)

简化,概念性,非数据库特定的解释:

当预先知道最大可能记录长度时,可以在恒定时间内找到记录的结尾/下一记录的开头。这是因为该位置可以使用简单的加法来计算,非常类似于数组索引。想象一下,我使用int作为记录的指针,并且记录大小是在某处定义的整数常量。然后,从当前记录位置到下一个:

int current_record = /* whatever */;
int next_record = current_record + FIXED_RECORD_SIZE;

就是这样!

或者,当使用字符串终止(或以其他方式分隔)的记录和字段时,您可以想象通过线性时间扫描找到下一个字段/记录,该扫描必须查找每个字符,直到找到分隔符。和以前一样,

char DELIMITER = ','; // or whatever
int current_record = /* whatever */;
int next_record = current_record;
while(character_at_location(next_record) != DELIMITER) {
    next_record++;
}

这可能是现实世界实现的简化或天真版本,但总体思路仍然存在:你不能轻易地在恒定时间内做同样的操作,即使它是恒定的时间,它也不可能是与执行单个添加操作一样快。

答案 1 :(得分:0)

我检查了这个,在我的情况下性能恶化了!我有一个带有整数值的1GB csv文件,每个文件长度为10个字符,填充,字段用","和记录用" \ n"分隔。我必须遵循脚本(我也尝试设置固定的记录大小并删除ltrim,但它没有帮助)。

SQL> CREATE TABLE ints_ext (id0 NUMBER(10),
  2                  id1 NUMBER(10),
  3                  id2 NUMBER(10),
  4                  id3 NUMBER(10),
  5                  id4 NUMBER(10),
  6                  id5 NUMBER(10),
  7                  id6 NUMBER(10),
  8                  id7 NUMBER(10),
  9                  id8 NUMBER(10),
 10                  id9 NUMBER(10))
 11  ORGANIZATION EXTERNAL (
 12  TYPE oracle_loader
 13  DEFAULT DIRECTORY tpch_dir
 14  ACCESS PARAMETERS (
 15         RECORDS DELIMITED BY NEWLINE
 16         BADFILE 'bad_%a_%p.bad'
 17         LOGFILE 'log_%a_%p.log'
 18         FIELDS TERMINATED BY ','
 19         MISSING FIELD VALUES ARE NULL)
 20  LOCATION ('data1_1.csv'))
 21  parallel 1
 22  REJECT LIMIT 0
 23  NOMONITORING;

SQL> select count(*) from ints_ext;

  COUNT(*)
----------
   9761289

Elapsed: 00:00:43.68
SQL> select /*+ parallel(1) tracing(STRIP,1) */ * from ints_ext;

no rows selected

Elapsed: 00:00:43.78

SQL> CREATE TABLE ints_ext (id0 NUMBER(10),
  2                  id1 NUMBER(10),
  3                  id2 NUMBER(10),
  4                  id3 NUMBER(10),
  5                  id4 NUMBER(10),
  6                  id5 NUMBER(10),
  7                  id6 NUMBER(10),
  8                  id7 NUMBER(10),
  9                  id8 NUMBER(10),
 10                  id9 NUMBER(10))
 11  ORGANIZATION EXTERNAL (
 12  TYPE oracle_loader
 13  DEFAULT DIRECTORY tpch_dir
 14  ACCESS PARAMETERS (
 15         RECORDS DELIMITED BY NEWLINE
 16         BADFILE 'bad_%a_%p.bad'
 17         LOGFILE 'log_%a_%p.log'
 18         FIELDS ltrim (
 19         id0 position(1:10) char(10),
 20         id1 position(12:21) char(10),
 21         id2 position(23:32) char(10),
 22         id3 position(34:43) char(10),
 23         id4 position(45:54) char(10),
 24         id5 position(56:65) char(10),
 25         id6 position(67:76) char(10),
 26         id7 position(78:87) char(10),
 27         id8 position(89:98) char(10),
 28         id9 position(100:109) char(10)
 29         ))
 30  LOCATION ('data1_1.csv'))
 31  parallel 1
 32  REJECT LIMIT 0
 33  NOMONITORING;

SQL> select count(*) from ints_ext;


  COUNT(*)
----------
   9761289

Elapsed: 00:00:50.38
SQL> 
select /*+ parallel(1) tracing(STRIP,1) */ * from ints_ext;

no rows selected

Elapsed: 00:00:45.26