SQL*Loader的强大功能
SQL*Loader 是 Oracle 提供的导入实用程序,特别针对从外部文件导入大批量数据进入数据库表。该工具已经有多年的历史,每一次版本升级都使其更加强大、灵活和快捷,但遗憾的是它的语法却是神秘而不直观,并且只能从命令行窗口处进行调用。
尽管它有不直观的缺点,但却是最快最有效的导入数据方法。缺省情况下它使用 "conventional path" 常规选项来批量导入数据,其性能提高度并不明显。我建议使用更快速的导入参数选项,在命令行添加"direct=true" 选项调用 "direct path" 导入选项。在 "direct path" 导入实现中,程序在数据库表的新数据块的 high water mark 处直接写入导入数据,缩短了数据插入的处理时间,同时优化使用了非常有效的B+二叉树方法来更新表的索引。
运用这种方法,如果使用缺省的 conventional path 导入选项,总的导入时间是 81 秒,进程占用 CPU 时间大约是 12 秒,这包括了更新表的索引时间。如果使用 direct path 导入选项,总的导入时间竟是 9 秒,进程占用 CPU 时间也仅仅是 3 秒,也包括了更新表的索引时间。
由此可见,尽管表中的索引在数据导入之前并没有被删除,使用SQL*Loader的direct path 导入选项仍然是快速和有效的。当然它也有缺点,就像NOLOGGING关键字一样该方法不生成REDO日志数据,导入进程出错后将无法恢复到先前状态;在数据导入过程中表的索引是不起作用的,用户此时访问该表时将出现迟缓,当然在数据导入的过程中最好不要让用户访问表。
分区交换 (Partition Exchange)
以上讨论的数据导入方法都有一个限制,就是要求用户在导入数据完成之后才可以访问数据库表。面对7×24不间断访问数据库来说,如果我们只是导入需要增加的数据时,这种限制将对用户的实时访问产生影响。Oracle在这方面提供了表分区功能,它可以减少导入数据操作对用户实时访问数据的影响,操作模式就象使用可热插拔的硬盘一样,只不过这里的硬盘换成了分区(Partition)而已。需要声明的是 Partitioning 分区功能只有在企业版数据库中才提供。
在一个被分区过的表中,呈现给用户的表是多个分区段(segments)的集合。分区可以在需要时被添加,在维护时被卸载或删除,分区表可以和数据库中的表交换数据,只要它们的表结构和字段类型是一致的,交换后的分区表将拥有与之互动的表的数据。需要注意的是,这种交换只是在Oracle数据库的数据字典层面上进行,并没有数据被实际移动,所以分区表交换是极其快速的。
为了创建实验环境,先假设CALLS表是个分区表,要创建一个空的分区PART_01012004,用来保存2004年1月1日的呼叫数据。然后需要再创建一临时表为CALLS_TEMP,该表与CALLS表拥有相同的字段和数据类型。
我们使用先前介绍的导入方法将十万条数据导入到CALLS_TEMP表中,可以耐心等待数据完全导入到CALLS_TEMP表中,并且创建好索引和相关约束条件,所有这一切操作并不影响用户实时访问CALLS表,因为我们只对CALLS_TEMP临时表进行了操作。一旦数据导入完成,CALLS_TEMP表就存有2004年1月1日的呼叫数据。同时利用CALLS表中名为PART_01012004的空分区,使用如下语句执行分区交换:
ALTER TABLE calls
EXCHANGE PARTITION part_01012004 WITH TABLE calls_temp
INCLUDING INDEXES WITHOUT VALIDATION;
分区交换操作将非常快速地只更新CALLS表的数据字典,PART_01012004分区表即刻拥有CALLS_TEMP表的所有数据,而CALLS_TEMP表变为空表。假定CALLS表使用局部索引而非全局索引,上述语句中的INCLUDING INDEXES将保证分区交换包括索引的可用性,WITHOUT VALIDATION 指明不检查交替表中数据的匹配,加快了交换的速度。
结论
以上探讨了Oracle数据库的多种数据导入方法,每种方法都有其优缺点和适用环境,能够满足你不同的导入需求,当然你需要在了解了这些方法后,在速度、简易性、灵活性、可恢复性和数据可用性之间寻求最佳导入方案。
为了对比各种方法的效果,我们创建了一个实例来展示各种方法的导入效率和效果,从中你可以选择最适合的方法用于今后的数据导入工作。同时请记住,本文并未囊括所有的ORACLE数据导入技术(比如并行数据导入技术),这需要我们继续不懈的探索和尝试。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/14855094/viewspace-425579/
,如需转载,请注明出处,否则将追究法律责任。