设为首页 收藏本站
查看: 660|回复: 0

[经验分享] Oracle 【直接加载】全方位解析与性能优化

[复制链接]

尚未签到

发表于 2018-9-14 11:05:38 | 显示全部楼层 |阅读模式
  1.比较sql*loader使用conventional传统 和direct直接 方式加载的性能差异。
  一、概念
  1.直接加载优势
  (1)直接加载比传统加载效率要高
  (2)不扫描原来的空数据块
  (3)不需要sql解析,减少系统的负载
  (4)不经过SGA
  (5)不走DBWR进程,走自己的专属进程,所以速度快
  2.直接加载限制
  (1)不能加载簇表
  (2)锁定整个表,在表上有活动事务的时候不能加载
  3.直接加载特点
  (1)直接加载是在所有数据块后面加载新数据块,修改高水位线,不扫描原来的空数据块。
  (2)直接加载只产生一点点的管理redo,因为要修改数据字典(也可以讲不产生redo)。
  (3)回滚,如果加载失败把新分配数据块抹掉就行了。
  (4)无需SGA,无需SQL解析,无需DBWR进程
  二、实验
  1.现在我们已经定义了leo_test_sqlload;
  LS@LEO> select count(*) from leo_test_sqlload;    现在表里没有记录数
  COUNT(*)
  ----------
  0
  LS@LEO> select segment_name,extent_id,bytes from user_extents where segment_name='LEO_TEST_SQLLOAD';     现在分配了1个区
  SEGMENT_NAME                                                                       EXTENT_ID      BYTES
  --------------------------------------------------------------------------------- ---------- ----------
  LEO_TEST_SQLLOAD                                                                           0      65536
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log    传统方式加载数据

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  LS@LEO> select count(*) from leo_test_sqlload;                   已经成功加载了10万条数据
  COUNT(*)
  ----------
  100000
  LS@LEO> select segment_name,extent_id,bytes from user_extents where segment_name='LEO_TEST_SQLLOAD';      10万条数据占用23个数据块
  SEGMENT_NAME                                                                       EXTENT_ID      BYTES
  --------------------------------------------------------------------------------- ---------- ----------
  LEO_TEST_SQLLOAD                                                                           0      65536
  LEO_TEST_SQLLOAD                                                                           1      65536
  LEO_TEST_SQLLOAD                                                                           2      65536
  LEO_TEST_SQLLOAD                                                                           3      65536
  LEO_TEST_SQLLOAD                                                                           4      65536
  LEO_TEST_SQLLOAD                                                                           5      65536
  LEO_TEST_SQLLOAD                                                                           6      65536
  LEO_TEST_SQLLOAD                                                                           7      65536
  LEO_TEST_SQLLOAD                                                                           8      65536
  LEO_TEST_SQLLOAD                                                                           9      65536
  LEO_TEST_SQLLOAD                                                                          10      65536
  LEO_TEST_SQLLOAD                                                                          11      65536
  LEO_TEST_SQLLOAD                                                                          12      65536
  LEO_TEST_SQLLOAD                                                                          13      65536
  LEO_TEST_SQLLOAD                                                                          14      65536
  LEO_TEST_SQLLOAD                                                                          15      65536
  LEO_TEST_SQLLOAD                                                                          16    1048576
  LEO_TEST_SQLLOAD                                                                          17    1048576
  LEO_TEST_SQLLOAD                                                                          18    1048576
  LEO_TEST_SQLLOAD                                                                          19    1048576
  LEO_TEST_SQLLOAD                                                                          20    1048576
  LEO_TEST_SQLLOAD                                                                          21    1048576
  LEO_TEST_SQLLOAD                                                                          22    1048576
  23 rows selected.
  LS@LEO> delete from leo_test_sqlload;                     删除10万条数据
  100000 rows deleted.
  LS@LEO> commit;                                           提交
  Commit complete.
  LS@LEO> select segment_name,extent_id,bytes from user_extents where segment_name='LEO_TEST_SQLLOAD';
  SEGMENT_NAME                                                                       EXTENT_ID      BYTES
  --------------------------------------------------------------------------------- ---------- ----------
  LEO_TEST_SQLLOAD                                                                           0      65536
  LEO_TEST_SQLLOAD                                                                           1      65536
  LEO_TEST_SQLLOAD                                                                           2      65536
  LEO_TEST_SQLLOAD                                                                           3      65536
  LEO_TEST_SQLLOAD                                                                           4      65536
  LEO_TEST_SQLLOAD                                                                           5      65536
  LEO_TEST_SQLLOAD                                                                           6      65536
  LEO_TEST_SQLLOAD                                                                           7      65536
  LEO_TEST_SQLLOAD                                                                           8      65536
  LEO_TEST_SQLLOAD                                                                           9      65536
  LEO_TEST_SQLLOAD                                                                          10      65536
  LEO_TEST_SQLLOAD                                                                          11      65536
  LEO_TEST_SQLLOAD                                                                          12      65536
  LEO_TEST_SQLLOAD                                                                          13      65536
  LEO_TEST_SQLLOAD                                                                          14      65536
  LEO_TEST_SQLLOAD                                                                          15      65536
  LEO_TEST_SQLLOAD                                                                          16    1048576
  LEO_TEST_SQLLOAD                                                                          17    1048576
  LEO_TEST_SQLLOAD                                                                          18    1048576
  LEO_TEST_SQLLOAD                                                                          19    1048576
  LEO_TEST_SQLLOAD                                                                          20    1048576
  LEO_TEST_SQLLOAD                                                                          21    1048576
  LEO_TEST_SQLLOAD                                                                          22    1048576
  23 rows selected.
  有人会问我们把数据都删除了为什么还占用空间呢,呵呵,oracle的delete操作不回收空间,只是把自己的记录标记为删除,实际呢还占用的空间不释放
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log    第二次传统方式加载数据

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  LS@LEO> select count(*) from leo_test_sqlload;                   已经成功加载了10万条数据
  COUNT(*)
  ----------
  100000
  LS@LEO> select segment_name,extent_id,bytes from user_extents where segment_name='LEO_TEST_SQLLOAD';
  SEGMENT_NAME                                                                       EXTENT_ID      BYTES
  --------------------------------------------------------------------------------- ---------- ----------
  LEO_TEST_SQLLOAD                                                                           0      65536
  LEO_TEST_SQLLOAD                                                                           1      65536
  LEO_TEST_SQLLOAD                                                                           2      65536
  LEO_TEST_SQLLOAD                                                                           3      65536
  LEO_TEST_SQLLOAD                                                                           4      65536
  LEO_TEST_SQLLOAD                                                                           5      65536
  LEO_TEST_SQLLOAD                                                                           6      65536
  LEO_TEST_SQLLOAD                                                                           7      65536
  LEO_TEST_SQLLOAD                                                                           8      65536
  LEO_TEST_SQLLOAD                                                                           9      65536
  LEO_TEST_SQLLOAD                                                                          10      65536
  LEO_TEST_SQLLOAD                                                                          11      65536
  LEO_TEST_SQLLOAD                                                                          12      65536
  LEO_TEST_SQLLOAD                                                                          13      65536
  LEO_TEST_SQLLOAD                                                                          14      65536
  LEO_TEST_SQLLOAD                                                                          15      65536
  LEO_TEST_SQLLOAD                                                                          16    1048576
  LEO_TEST_SQLLOAD                                                                          17    1048576
  LEO_TEST_SQLLOAD                                                                          18    1048576
  LEO_TEST_SQLLOAD                                                                          19    1048576
  LEO_TEST_SQLLOAD                                                                          20    1048576
  LEO_TEST_SQLLOAD                                                                          21    1048576
  LEO_TEST_SQLLOAD                                                                          22    1048576
  23 rows selected.
  使用传统方式加载数据,会扫描原来的空数据块,会把新加载的数据插入到空数据块内,看我们还是使用原来的23个数据块
  LS@LEO> delete from leo_test_sqlload;                     这是第二次删除10万条数据
  100000 rows deleted.
  LS@LEO> commit;                                           提交
  Commit complete.
  LS@LEO> select segment_name,extent_id,bytes from user_extents where segment_name='LEO_TEST_SQLLOAD';
  SEGMENT_NAME                                                                       EXTENT_ID      BYTES
  --------------------------------------------------------------------------------- ---------- ----------
  LEO_TEST_SQLLOAD                                                                           0      65536
  LEO_TEST_SQLLOAD                                                                           1      65536
  LEO_TEST_SQLLOAD                                                                           2      65536
  LEO_TEST_SQLLOAD                                                                           3      65536
  LEO_TEST_SQLLOAD                                                                           4      65536
  LEO_TEST_SQLLOAD                                                                           5      65536
  LEO_TEST_SQLLOAD                                                                           6      65536
  LEO_TEST_SQLLOAD                                                                           7      65536
  LEO_TEST_SQLLOAD                                                                           8      65536
  LEO_TEST_SQLLOAD                                                                           9      65536
  LEO_TEST_SQLLOAD                                                                          10      65536
  LEO_TEST_SQLLOAD                                                                          11      65536
  LEO_TEST_SQLLOAD                                                                          12      65536
  LEO_TEST_SQLLOAD                                                                          13      65536
  LEO_TEST_SQLLOAD                                                                          14      65536
  LEO_TEST_SQLLOAD                                                                          15      65536
  LEO_TEST_SQLLOAD                 ,                                                         16    1048576
  LEO_TEST_SQLLOAD                                                                          17    1048576
  LEO_TEST_SQLLOAD                                                                          18    1048576
  LEO_TEST_SQLLOAD                                                                          19    1048576
  LEO_TEST_SQLLOAD                                                                          20    1048576
  LEO_TEST_SQLLOAD                                                                          21    1048576
  LEO_TEST_SQLLOAD                                                                          22    1048576
  23 rows selected.
  delete还是不回收空间,我们依然占用着23个数据块
  Sun Sep  9 20:25:04 CST 2012
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true    直接方式加载数据

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Load completed - logical record count 100000.
  [oracle@secdb1 ~]$ date
  Sun Sep  9 20:25:14 CST 2012                      看我们才用了10秒时间,比传统加载效率高很多
  LS@LEO> select segment_name,extent_id,bytes from user_extents where segment_name='LEO_TEST_SQLLOAD';
  SEGMENT_NAME                                                                       EXTENT_ID      BYTES
  --------------------------------------------------------------------------------- ---------- ----------
  LEO_TEST_SQLLOAD                                                                           0      65536
  LEO_TEST_SQLLOAD                                                                           1      65536
  LEO_TEST_SQLLOAD                                                                           2      65536
  LEO_TEST_SQLLOAD                                                                           3      65536
  LEO_TEST_SQLLOAD                                                                           4      65536
  LEO_TEST_SQLLOAD                                                                           5      65536
  LEO_TEST_SQLLOAD                                                                           6      65536
  LEO_TEST_SQLLOAD                                                                           7      65536
  LEO_TEST_SQLLOAD                                                                           8      65536
  LEO_TEST_SQLLOAD                                                                           9      65536
  LEO_TEST_SQLLOAD                                                                          10      65536
  LEO_TEST_SQLLOAD                                                                          11      65536
  LEO_TEST_SQLLOAD                                                                          12      65536
  LEO_TEST_SQLLOAD                                                                          13      65536
  LEO_TEST_SQLLOAD                                                                          14      65536
  LEO_TEST_SQLLOAD                                                                          15      65536
  LEO_TEST_SQLLOAD                                                                          16    1048576
  LEO_TEST_SQLLOAD                                                                          17    1048576
  LEO_TEST_SQLLOAD                                                                          18    1048576
  LEO_TEST_SQLLOAD                                                                          19    1048576
  LEO_TEST_SQLLOAD                                                                          20    1048576
  LEO_TEST_SQLLOAD                                                                          21    1048576
  LEO_TEST_SQLLOAD                                                                          22    1048576
  LEO_TEST_SQLLOAD                                                                          23    1048576
  LEO_TEST_SQLLOAD                                                                          24    1048576
  LEO_TEST_SQLLOAD                                                                          25    1048576
  LEO_TEST_SQLLOAD                                                                          26    1048576
  LEO_TEST_SQLLOAD                                                                          27    1048576
  LEO_TEST_SQLLOAD                                                                          28    1048576
  LEO_TEST_SQLLOAD                                                                          29    1048576
  LEO_TEST_SQLLOAD                                                                          30    1048576
  31 rows selected.
  哈哈我们现在发现同样的10万条记录,竟然占用了31个数据块,传统加载只用了23个,而我们使用直接加载到多了8个数据块,有个上面的概念大家是不是有所启发呢,对了直接加载不扫描原来的空数据块,会在所有数据块之后加载新的数据块插入数据修改高水位线HWM,当提交事务之后,把高水位线移到新数据之后,其他的用户就可以看见了。
  2.比较直接加载使用conventional 和direct方式产生的redo大小(可以通过/*+ append */模拟直接加载)。
  明确:直接加载与logging配合下并不能显著的减少redo日志量
  直接加载与nologging配合下可以大幅度的减少redo日志量
  LS@LEO> create table leo_t1 as select * from leo_test_sqlload where 1=2;          创建leo_t1表
  Table created.

  LS@LEO>>
  Table>  LS@LEO> set autotrace trace stat;
  LS@LEO> insert into leo_t1 select * from leo_test_sqlload where rownum   680  bytes sent via SQL*Net to client
  603  bytes received via SQL*Net from client
  4  SQL*Net roundtrips to/from client
  6  sorts (memory)
  0  sorts (disk)
  20000  rows processed
  LS@LEO> rollback;                                                     回滚操作,使用undo表空间
  Rollback complete.
  LS@LEO> insert /*+ append */ into leo_t1 select * from leo_test_sqlload where rownum   664  bytes sent via SQL*Net to client
  617  bytes received via SQL*Net from client
  4  SQL*Net roundtrips to/from client
  1  sorts (memory)
  0  sorts (disk)
  20000  rows processed
  小结:这是因为在logging模式下,所有的数据块的改变都会产生redo日志,为以后恢复做准备,这时候直接加载没有多大的优势。
  直接加载与nologging配合下可以大幅度的减少redo日志量
  重大前提
  如果你的数据库开启了force_logging=yes模式,那么不管你是传统加载还是直接加载都不会减少redo产生量
  所以要想大幅度减少redo日志就必须满足3个条件

  (1)关闭force_logging选项    >
  (2)数据对象级别nologging模式>  (3)直接加载                 insert /*+ append */ into
  数据库归档与redo日志量关系
  数据库处于归档模式
  当表模式为logging状态时,无论是否使用append模式,都会生成redo.当表模式为nologging状态时,只有append模式,不会生成redo。
  数据库处于非归档模式
  无论是在logging还是nologing的模式下,append的模式都不会生成redo,而no append模式下都会生成redo。
  force_logging  logging nologging  如果都设置了  有一个优先级的 排名
  force_logging   可以在数据库级别   表空间级别设置
  logging nologging   只能在数据对象级别设置

  LS@LEO>>  LS@LEO> select force_logging from v$database;                       已经关闭force_logging选项
  FOR
  ---
  NO

  LS@LEO>>
  Table>  LS@LEO> select logging from user_tables where table_name='LEO_T1';
  LOG
  ---
  NO
  LS@LEO> select count(*) from leo_t1;                                       0条记录
  COUNT(*)
  ----------
  0
  LS@LEO> select index_name from user_indexes where table_name='LEO_T1';   表上没有索引
  no rows selected
  LS@LEO> insert /*+ append */ into leo_t1 select * from leo_test_sqlload where rownum   658  bytes sent via SQL*Net to client
  617  bytes received via SQL*Net from client
  4  SQL*Net roundtrips to/from client
  9  sorts (memory)
  0  sorts (disk)
  20000  rows processed
  LS@LEO> rollback;
  Rollback complete.
  LS@LEO> insert into leo_t1 select * from leo_test_sqlload where rownum   673  bytes sent via SQL*Net to client
  603  bytes received via SQL*Net from client
  4  SQL*Net roundtrips to/from client
  1  sorts (memory)
  0  sorts (disk)
  20000  rows processed
  小结:直接加载与nologging配合下可以大幅度的减少redo日志量,因为插入的数据不产生redo日志,所以在插入后要做备份操作,一旦数据损坏,就要使用备份来恢复,不能使用redo来恢复。注意要关闭force_logging选项哦!
  3.比较direct方式使用并行和非并行选项的性能差异。
  数据文件:leo_test.data   100000记录
  控制文件:leo_test.ctl
  日志文件:leo_test.log
  串行直接加载sqlload : sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true
  并行直接加载sqlload : sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true parallel=true
  1.现在演示“串行直接加载”
  LS@LEO> select count(*) from leo_test_sqlload;         加载之前
  COUNT(*)
  ----------
  0
  Sun Sep  9 10:58:24 CST 2012                           58:24
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Load completed - logical record count 100000.
  [oracle@secdb1 ~]$ date
  Sun Sep  9 10:58:45 CST 2012                          58:45-58:24=21秒  即用时21秒  我这是手算的,一会看看日志里记录的是多少
  LS@LEO> select count(*) from leo_test_sqlload;         加载之后
  COUNT(*)
  ----------
  100000
  [oracle@secdb1 ~]$ more leo_test.log

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Control File:   leo_test.ctl
  Data File:      leo_test.data
  Bad File:     leo_test.bad
  Discard File:  none specified
  (Allow all discards)
  Number to load: ALL
  Number to skip: 0
  Errors allowed: 50
  Continuation:    none specified
  Path used:      Direct            【sql*loader采用串行直接加载方式加载数据】
  Table LEO_TEST_SQLLOAD, loaded from every logical record.                              加载的表名
  Insert option in effect for this table: APPEND                                         追加方式加载数据
  TRAILING NULLCOLS option in effect
  Column Name                  Position   Len  Term Encl Datatype                     列名
  ------------------------------ ---------- ----- ---- ---- ---------------------
  START_TIME                          FIRST     *   |       DATE YYYY-MM-DD HH24:MI:SS
  END_TIME                             NEXT     *   |       DATE YYYY-MM-DD HH24:MI:SS
  PROTOCOL                             NEXT     *   |       CHARACTER
  PRIVATE_IP                           NEXT     *   |       CHARACTER
  PRIVATE_PORT                         NEXT     *   |       CHARACTER
  SRC_IP                               NEXT     *   |       CHARACTER
  SRC_PORT                             NEXT     *   |       CHARACTER
  DEST_IP                              NEXT     *   |       CHARACTER
  DEST_PORT                            NEXT     *   |       CHARACTER
  The following index(es) on table LEO_TEST_SQLLOAD were processed:                     并把索引也加载了10万个索引键值
  index LS.LEO_INDEX1 loaded successfully with 100000 keys
  Table LEO_TEST_SQLLOAD:
  100000 Rows successfully loaded.                                                    成功加载10万行记录
  0 Rows not loaded due to data errors.                                               由于数据错误,0行没有加载
  0 Rows not loaded because all WHEN clauses were failed.                             因为所有条款都失败的时候,0行没有加载
  0 Rows not loaded because all fields were null.                                     因为所有字段都是空的,0行没有加载
  Date cache:

  Max>  Entries :        65
  Hits    :    199935
  Misses  :         0

  Bind array>  Column array  rows :    5000
  Stream buffer bytes:  256000
  Read   buffer bytes: 1048576
  Total logical records skipped:          0                             跳过逻辑记录数总和0
  Total logical records read:        100000                             读取逻辑记录数总和100000
  Total logical records rejected:         0                             拒绝逻辑记录数总和0
  Total logical records discarded:        0                             丢弃逻辑记录数总和0
  Total stream buffers loaded by SQL*Loader main thread:       26
  Total stream buffers loaded by SQL*Loader load thread:       17
  Run began on Sun Sep 09 10:58:26 2012                                 开始的时间
  Run ended on Sun Sep 09 10:58:41 2012                                 结束的时间
  Elapsed time was:     00:00:14.70                                     即用时14.7秒  这是机器算的
  CPU time was:         00:00:00.38                                     CPU占用0.38秒
  2.现在演示“并行直接加载”
  并行加载
  (1)并行加载和并行insert机制差不多
  (2)并行加载可以启动多个并行进程,同时加载多个文件
  (3)并行加载可以启动多个并行进程,分拆一个文件加载
  LS@LEO> select count(*) from leo_test_sqlload;         加载之前
  COUNT(*)
  ----------
  0
  Sun Sep  9 11:28:13 CST 2012                          28:13
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true parallel=true

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Load completed - logical record count 100000.
  [oracle@secdb1 ~]$ date
  Sun Sep  9 11:28:28 CST 2012                          28:28-28:13=15秒  即用时15秒  我这是手算的,一会看看日志里记录的是多少
  LS@LEO> select count(*) from leo_test_sqlload;        加载之后
  COUNT(*)
  ----------
  100000
  [oracle@secdb1 ~]$ more leo_test.log

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Control File:   leo_test.ctl
  Data File:      leo_test.data
  Bad File:     leo_test.bad
  Discard File:  none specified
  (Allow all discards)
  Number to load: ALL
  Number to skip: 0
  Errors allowed: 50
  Continuation:    none specified
  Path used:      Direct - with parallel option.             【sql*loader采用并行直接加载方式加载数据】
  Table LEO_TEST_SQLLOAD, loaded from every logical record.   加载的表名
  Insert option in effect for this table: APPEND              追加的方式加载数据
  TRAILING NULLCOLS option in effect
  Column Name                  Position   Len  Term Encl Datatype                      列名
  ------------------------------ ---------- ----- ---- ---- ---------------------
  START_TIME                          FIRST     *   |       DATE YYYY-MM-DD HH24:MI:SS
  END_TIME                             NEXT     *   |       DATE YYYY-MM-DD HH24:MI:SS
  PROTOCOL                             NEXT     *   |       CHARACTER
  PRIVATE_IP                           NEXT     *   |       CHARACTER
  PRIVATE_PORT                         NEXT     *   |       CHARACTER
  SRC_IP                               NEXT     *   |       CHARACTER
  SRC_PORT                             NEXT     *   |       CHARACTER
  DEST_IP                              NEXT     *   |       CHARACTER
  DEST_PORT                            NEXT     *   |       CHARACTER
  Table LEO_TEST_SQLLOAD:
  100000 Rows successfully loaded.                                                      成功加载10万行记录
  0 Rows not loaded due to data errors.                                                 由于数据错误,0行没有加载
  0 Rows not loaded because all WHEN clauses were failed.                               因为所有条款都失败的时候,0行没有加载
  0 Rows not loaded because all fields were null.                                       因为所有字段都是空的,0行没有加载
  Date cache:

  Max>  Entries :        65
  Hits    :    199935
  Misses  :         0

  Bind array>  Column array  rows :    5000
  Stream buffer bytes:  256000
  Read   buffer bytes: 1048576
  Total logical records skipped:          0                                               跳过逻辑记录数总和0
  Total logical records read:        100000                                               读取逻辑记录数总和100000
  Total logical records rejected:         0                                               拒绝逻辑记录数总和0
  Total logical records discarded:        0                                               丢弃逻辑记录数总和0
  Total stream buffers loaded by SQL*Loader main thread:       26
  Total stream buffers loaded by SQL*Loader load thread:       17
  Run began on Sun Sep 09 11:28:14 2012                            开始的时间
  Run ended on Sun Sep 09 11:28:24 2012                            结束的时间
  Elapsed time was:     00:00:09.18                                即用时9.18秒  这是机器算的
  CPU time was:         00:00:00.42                                CPU占用0.38秒
  小结:从时间效率上看“并行直接加载”比“串行直接加载”的效率要高,但我们都知道“并行直接加载”如果表中有索引会导致加载失败,因为oracle不能一边并行一边维护索引的完整性。
  4.直接加载对约束性索引和非约束型索引的影响。
  一、条件
  (1)现在我们使用sql*load来加载100000条数据
  (2)加载的leo_test_sqlload表上有索引
  二、实验
  1.非约束性索引,直接加载在加载完成后会维护索引的完整性
  $ cat leo_test.data | wc -l                              检查数据文件内的记录数10万条,这就是我们要加载的数据
  100000
  $ cat leo_test.ctl                                       控制文件内容
  LOAD   DATA
  INFILE '/home/oracle/leo_test.data'                      数据源
  APPEND INTO   TABLE leo_test_sqlload                     加载数据的表
  FIELDS   TERMINATED   BY '|'                             文本数据的分隔符
  TRAILING   NULLCOLS
  (START_TIME DATE 'YYYY-MM-DD HH24:MI:SS',END_TIME DATE 'YYYY-MM-DD HH24:MI:SS',PROTOCOL,PRIVATE_IP,PRIVATE_PORT
  ,SRC_IP,SRC_PORT,DEST_IP,DEST_PORT)                      表中字段的名
  LS@LEO> desc leo_test_sqlload;                           表的结构
  Name                                      Null?    Type
  ----------------------------------------- -------- ----------------------------
  START_TIME                                         DATE
  END_TIME                                           DATE
  PROTOCOL                                           VARCHAR2(20)
  PRIVATE_IP                                         VARCHAR2(20)
  PRIVATE_PORT                                       VARCHAR2(20)
  SRC_IP                                             VARCHAR2(20)
  SRC_PORT                                           VARCHAR2(20)
  DEST_IP                                            VARCHAR2(20)
  DEST_PORT                                          VARCHAR2(20)
  LS@LEO> select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD';   现在表上没有索引,我们定义一个索引
  no rows selected
  LS@LEO> create index leo_index1 on leo_test_sqlload(start_time);                          我们在start_time字段添加了索引
  Index created.
  LS@LEO> select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD';   索引已经生效
  INDEX_NAME                     STATUS
  ------------------------------ --------
  LEO_INDEX1                     VALID
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test.ctl data=leo_test.data log=leo_test.log direct=true  直接加载

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Load completed - logical record count 100000.
  LS@LEO> select count(*) from leo_test_sqlload;                                            已经加载了10万条记录
  COUNT(*)
  ----------
  100000
  LS@LEO> select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD';    索引状态还是有效的
  INDEX_NAME                     STATUS
  ------------------------------ --------
  LEO_INDEX1                     VALID
  小结:非约束索引下,直接加载会维护索引的完整性,在数据加载入库后索引还是有效的。
  2.约束性索引【主键】,直接加载依然会把数据加载入库,但索引会失效unusable,并且在日志中没有提示,必须手工rebuild重新建立
  数据文件:leo_test1.data
  控制文件:leo_test1.ctl
  日志文件:leo_test1.log
  sqlload : sqlldr userid=ls/ls control=leo_test1.ctl data=leo_test1.data log=leo_test1.log direct=true
  LS@LEO> desc leo_test_sqlload1                      表结构
  Name                                      Null?    Type
  ----------------------------------------- -------- ----------------------------
  START_TIME                                         DATE
  END_TIME                                           DATE
  PROTOCOL                                           VARCHAR2(20)
  PRIVATE_IP                                         VARCHAR2(20)
  PRIVATE_PORT                                       VARCHAR2(20)
  SRC_IP                                             VARCHAR2(20)
  SRC_PORT                                           VARCHAR2(20)
  DEST_IP                                            VARCHAR2(20)
  DEST_PORT                                          VARCHAR2(20)
  LS@LEO> select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD1';    没有主键,我们现在建一个
  no rows selected

  LS@LEO>>
  Table>  LS@LEO> select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD1';    主键已经生效
  INDEX_NAME                     STATUS
  ------------------------------ --------
  PK_LEO_TEST1                   VALID
  LS@LEO> select count(*) from leo_test_sqlload1;                                             表中没有数据我们开始加载
  COUNT(*)
  ----------
  0
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test1.ctl data=leo_test1.data log=leo_test1.log direct=true

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Load completed - logical record count 100.
  LS@LEO> select * from leo_test_sqlload1 where rownum  select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD1';    索引已经失效
  INDEX_NAME                     STATUS
  ------------------------------ --------
  PK_LEO_TEST1                   UNUSABLE
  结论:在OLAP系统中实时表不应该使用约束【因为是海量数据重复是正常的】,在维度表中可以使用约束。
  3.如果使用并行+直接加载数据的话,如果表中有索引,会导致加载失败,可以使用skip_index_maintenance选项“跳过索引维护”,来到达数据加载的目的,但是此时索引会无效unusable,必须手工rebuild重新建立
  重新搭建环境
  LS@LEO> truncate table leo_test_sqlload1;
  Table truncated.

  LS@LEO>>
  Table>
  LS@LEO>>
  Table>  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test1.ctl data=leo_test1.data log=leo_test1.log direct=true parallel=true

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  SQL*Loader-951: Error calling once/load initialization
  ORA-26002: Table LS.LEO_TEST_SQLLOAD1 has index defined upon it.           表上有索引定义导致加载失败
  [oracle@secdb1 ~]$ sqlldr userid=ls/ls control=leo_test1.ctl data=leo_test1.data log=leo_test1.log direct=true parallel=true
  skip_index_maintenance=true

  SQL*Loader:>  Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  Load completed - logical record count 100.
  LS@LEO> select count(*) from leo_test_sqlload1;
  COUNT(*)
  ----------
  100
  LS@LEO> select index_name,status from user_indexes where table_name='LEO_TEST_SQLLOAD1';     索引此时是无效状态
  INDEX_NAME                     STATUS
  ------------------------------ --------
  PK_LEO_TEST1                   UNUSABLE
  小结:这就告诉我们了并行就是切片,一边切片一边维护索引完整性是做不到的,我们只能在加载数据后重新建立索引。
  oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-582418-1-1.html 上篇帖子: oracle rman学习笔记 下篇帖子: 教您搞懂oracle字符集
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表