【问题标题】:How do "Fixed-length records" and "Fixed-length fields" increases database performance?“定长记录”和“定长字段”如何提高数据库性能?
【发布时间】:2013-01-26 15:29:16
【问题描述】:

谁能解释以下两个关于使用ORACLE_LOADER 访问驱动程序提高Oracle 外部表性能的语句:

  1. 固定长度记录的处理速度快于终止的记录 一个字符串。
  2. 固定长度字段的处理速度比分隔字段快。

用代码解释可能有助于我深入理解这个概念。这是两种语法:

固定字段长度

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;

【问题讨论】:

  • 如果您将阅读本文的位置包括在内,将会有所帮助。
  • 您想用哪种语言阅读解释您问题的代码?
  • @TildalWave 显然是预言机术语
  • 我怀疑您指的是 external tables 的(特定于 Oracle)功能,但问题并不清楚。
  • @CodeLover - 真的不知道,但你不应该对这里或其他任何地方的否决票过于敏感。你问了你的问题,你得到了回应,这才是最重要的。 @Matt Ball 也为您的问题添加了内容。 create table 函数本身在这两种情况下都不会变慢,但是访问 comma delimited variable length 表中的记录会,而不是使用 fixed field length 时。这一切都是关于在检索数据时识别记录位置及其数据长度。再次,请参阅@Matt Ball 答案以获得解释。

标签: oracle oracle11g external-tables


【解决方案1】:

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

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

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++;
}

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

【讨论】:

  • 你能用代码和图表解释一下吗,这可能有助于我们快速理解这个概念吗?
  • 我的第二个问题的答案和第一个问题的答案一样吗,和你上面的帖子一样吗?
  • 是的。字段与记录,在我的回答所涵盖的概念级别上几乎相同。
  • 滚动到this document 中的trim_spec 部分。它还使用 CHAR(1) 更改数据类型假设,将 CHAR(1) 用于非定界字段,将 CHAR(255) 用于定界字段(->来自 same document)。
【解决方案2】:

我检查了这个,在我的情况下,性能下降了!我有一个包含整数值的 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

【讨论】:

  • 将类型号改为char后也没有改善
猜你喜欢
  • 1970-01-01
  • 2019-12-25
  • 2015-11-28
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
  • 2020-03-29
相关资源
最近更新 更多