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

Oracle “固定长度记录”和“固定长度字段”如何提高数据库性能?,oracle,oracle11g,external-tables,Oracle,Oracle11g,External Tables,请任何人解释一下以下两种说法,即使用Oracle_LOADER访问驱动程序提高Oracle外部表性能: 固定长度记录的处理速度比由终止的记录快 一串。 固定长度字段的处理速度比分隔字段快。 用代码解释可能有助于我深入理解这个概念。以下是两个语法: 固定字段长度 逗号分隔 简化的概念性非数据库特定解释: 当预先知道最大可能记录长度时,可以在固定时间内找到记录的结束/下一条记录的开始。这是因为该位置可以使用简单的加法进行计算,非常类似于数组索引。假设我使用int作为指向记录的指针,并且记录大小是某个

请任何人解释一下以下两种说法,即使用Oracle_LOADER访问驱动程序提高Oracle外部表性能:

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

固定字段长度

逗号分隔


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

当预先知道最大可能记录长度时,可以在固定时间内找到记录的结束/下一条记录的开始。这是因为该位置可以使用简单的加法进行计算,非常类似于数组索引。假设我使用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++;
}

这可能是现实世界实现的简化版或幼稚版,但总体思路仍然是:在固定时间内无法轻松执行相同的操作,即使是固定时间,也不可能像执行单个添加操作那样快。

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

当预先知道最大可能记录长度时,可以在固定时间内找到记录的结束/下一条记录的开始。这是因为该位置可以使用简单的加法进行计算,非常类似于数组索引。假设我使用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++;
}

这可能是现实世界实现的简化版或幼稚版,但总体思路仍然是:在固定时间内无法轻松执行相同的操作,即使是固定时间,也不可能像执行单个添加操作一样快。

我检查了这一点,在我的例子中,性能恶化了!我有一个带整数值的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

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

如果您将阅读内容包括在内,会有所帮助。您想用什么语言阅读解释问题的代码?@TildalWave在oracle术语中显然我怀疑您指的是的特定于oracle的功能,但从问题中一点也不清楚。@CodeLover-真的不知道,但是你不应该对在这里或者其他任何地方的投票过于敏感。你问了你的问题,得到了回答,这才是最重要的。@Matt Ball也很好地回答了您问题中添加的内容。CREATETABLE函数本身在这两种情况下都不会变慢,但是访问逗号分隔的可变长度表中的记录会变慢,这与使用固定字段长度时相反。在检索数据时,所有这些都是关于识别记录位置及其数据长度的。再次,请参阅@Matt Ball answer以获取解释。如果您将阅读内容包括在内,这会有所帮助。您想用什么语言阅读解释问题的代码?@TildalWave(oracle术语)显然我怀疑您指的是的特定于oracle的功能,但从问题中一点也不清楚。@CodeLover-真的不知道,但是你不应该对在这里或者其他任何地方的投票过于敏感。你问了你的问题,得到了回答,这才是最重要的。@Matt Ball也很好地回答了您问题中添加的内容。CREATETABLE函数本身在这两种情况下都不会变慢,但是访问逗号分隔的可变长度表中的记录会变慢,这与使用固定字段长度时相反。在检索数据时,所有这些都是关于识别记录位置及其数据长度的。再次,请参见@Matt Ball answer进行解释。您能解释一下吗
通过代码和图表,这可能会帮助我们快速理解这个概念?我的第二个问题的答案和第一个问题的答案是否相同,就像你在上面的帖子中一样?是的。字段与记录,在我的答案所涵盖的概念层面上几乎相同。滚动到中的“修剪规格”部分。它还改变了数据类型假设,对于非delimited字段使用CHAR1,对于delimited字段使用CHAR255->从中改变数据类型假设。@TildalWave direct link:您能用代码和图表来解释这一点吗,这可能有助于我们快速理解这个概念?我的第二个问题的答案与第一个问题的答案是否相同,如您在上面的帖子中所述?是的。字段与记录,在我的答案所涵盖的概念层面上几乎相同。滚动到中的“修剪规格”部分。它还更改了数据类型假设,对于非delimited字段,使用CHAR1;对于分隔字段,使用CHAR255->从该字段更改数据类型假设。@TildalWave direct link:将类型号更改为chara后也没有改进将类型号更改为char后也没有改进