由于使用imp实际上是作了大量的跟普通方式一样的insert
imp yz/yz indexes=n buffer=2800000 ignore=y feedback=10000 full=y file=yz.dmp |
--------------------------------
导入工具imp可能出现的问题
(1) 数据库对象已经存在
一般情况, 导入数据前应该彻底删除目标数据下的表, 序列, 函数/过程,触发器等;
数据库对象已经存在, 按缺省的imp参数, 则会导入失败
如果用了参数ignore=y, 会把exp文件内的数据内容导入
如果表有唯一关键字的约束条件, 不合条件将不被导入
如果表没有唯一关键字的约束条件, 将引起记录重复
(2) 数据库对象有主外键约束
不符合主外键约束时, 数据会导入失败
解决办法: 先导入主表, 再导入依存表
disable目标导入对象的主外键约束, 导入数据后, 再enable它们
(3) 权限不够
如果要把A用户的数据导入B用户下, A用户需要有imp_full_database权限
(4) 导入大表( 大于80M ) 时, 存储分配失败
默认的EXP时, compress = Y, 也就是把所有的数据压缩在一个数据块上.
导入时, 如果不存在连续一个大数据块, 则会导入失败.
导出80M以上的大表时, 记得compress= N, 则不会引起这种错误.
(5) imp和exp使用的字符集不同
如果字符集不同, 导入会失败, 可以改变unix环境变量或者NT注册表里NLS_LANG相关信息.
导入完成后再改回来.
(6) imp和exp版本不能往上兼容
imp可以成功导入低版本exp生成的文件, 不能导入高版本exp生成的文件
根据情况我们可以用
$ imp username/password@connect_string
说明: connect_string 是在/ORACLE_HOME/network/admin/tnsnames.ora
定义的本地或者远端数据库的名称
注意事项:
UNIX: /etc/hosts 要定义本地或者远端数据库服务器的主机名
win98: windows\hosts 和IP地址的对应关系
win2000: winnt\system32\drivers\etc\hosts
----------------------------------------------------------------------------------------
命令详解:
exp -help
USERID 必须是命令行中的第一个参数。
关键字 说明(默认)
---------------------------------------------------
USERID 用户名/口令
FULL 导出整个文件 (N)
BUFFER 数据缓冲区的大小
OWNER 所有者用户名列表
FILE 输出文件 (EXPDAT.DMP)
TABLES 表名列表
COMPRESS 导入一个范围 (Y)
RECORDLENGTH IO 记录的长度
GRANTS 导出权限 (Y)
INCTYPE 增量导出类型
INDEXES 导出索引 (Y)
RECORD 跟踪增量导出 (Y)
ROWS 导出数据行 (Y)
PARFILE 参数文件名
CONSTRAINTS 导出限制 (Y)
CONSISTENT 交叉表一致性
LOG 屏幕输出的日志文件
STATISTICS 分析对象 (ESTIMATE)
DIRECT 直接路径 (N)
TRIGGERS 导出触发器 (Y)
FEEDBACK 显示每 x 行 (0) 的进度
FILESIZE 各转储文件的最大尺寸
QUERY 选定导出表子集的子句
下列关键字仅用于可传输的表空间
TRANSPORT_TABLESPACE 导出可传输的表空间元数据 (N)
TABLESPACES 将传输的表空间列表
imp -help
USERID 必须是命令行中的第一个参数。
关键字 说明(默认)
----------------------------------------------
USERID 用户名/口令
FULL 导入整个文件 (N)
BUFFER 数据缓冲区大小
FROMUSER 所有人用户名列表
FILE 输入文件 (EXPDAT.DMP)
TOUSER 用户名列表
SHOW 只列出文件内容 (N)
TABLES 表名列表
IGNORE 忽略创建错误 (N)
RECORDLENGTH IO 记录的长度
GRANTS 导入权限 (Y)
INCTYPE 增量导入类型
INDEXES 导入索引 (Y)
COMMIT 提交数组插入 (N)
ROWS 导入数据行 (Y)
PARFILE 参数文件名
LOG 屏幕输出的日志文件
CONSTRAINTS 导入限制 (Y)
DESTROY 覆盖表空间数据文件 (N)
INDEXFILE 将表/索引信息写入指定的文件
SKIP_UNUSABLE_INDEXES 跳过不可用索引的维护 (N)
ANALYZE 执行转储文件中的 ANALYZE 语句 (Y)
FEEDBACK 显示每 x 行 (0) 的进度
TOID_NOVALIDATE 跳过指定类型 id 的校验
FILESIZE 各转储文件的最大尺寸
RECALCULATE_STATISTICS 重新计算统计值 (N)
下列关键字仅用于可传输的表空间
TRANSPORT_TABLESPACE 导入可传输的表空间元数据 (N)
TABLESPACES 将要传输到数据库的表空间
DATAFILES 将要传输到数据库的数据文件
TTS_OWNERS 拥有可传输表空间集中数据的用户
----------------------------------
转
资:由于工作需要,用oracle imp工具导入300W条记录到一张表中,使用的最简单的语句imp file=XXX.dmp full=y ignore=y.结果漫长的等待了快1个小时才导入完成。(硬件是Dell 2850 ,memory 8G)
治:imp时加入buffer=4096000 使导入时间缩短为10分钟左右
通:首先了解Oracle IMP的过程:如下图所示
1、import 进程读取DMP文件,准备数据并传输到数据系统中(这个过程是单线程的,纯顺序读IO,IO等待是这阶段慢的主要原因)
2、数据库等待从import进程中输入的数据后插入表中,之后再次等待从import进程来的新数据。在插入数据库的过程中分别使用DBW0和LOGWR两个oracle进程处理。DBW0负责插入新的数据和建立索引。LOGWR负责写日志文件。
从上述过程中,我们要提升IMP的效率,可以从几个方面来优化:
a)在阶段1的过程中,既然是顺序读,那么可以一次读多点,减少了读的次数,从而提高效率。在这方面buffer是一个不错的选择。imp的参数列表中有一个buffer参数。这个buffer参数的设置不是来源于database的,而是来源于IMP命令。参见<exp/imp >。那么buffer参数的能设置的大小仅仅受限于操作系统的限制。
b)在阶段2中,可以通过增加db_cache_size的大小,来提高DBW0的效率;适当增加 log_buffer的大小,来提高LOGWR的效率。
c)将建立索引放到imp后再建立,减少DBW0的时间
d) 如果数据库为归档模式,IMP前调整为非归档模式,从而减少LOGWR的压力
鉴:Oracle IMP 默认的buffer为4096byte, 采用加大buffer的方法,提高imp效率,仅仅是一种手段而已,只有对整个过程的把握,才能清晰明白优化的思路.
-----
imp调优例子
這次執行資料搬移的效率與第一次比較,有了很明顯的提高,下面對相應的優化作介紹,主要從系統級別的改變、init.ora參數的改變、import選項的改變三個方面來介紹如何實現提高import工具的執行性能,對於一個很大的資料搬移作業而言,import過程有時要花費幾個小時甚至幾天時間才能成功地完成。但是,在許多情況下,import需要對資料庫進行故障的恢復,這時對時間的要求比較高,因而這種性能是不能勝任的。此時可以做一些基本的調整,盡可能地縮小整個imp的時間,
1、IMP速度慢的原因
(1)、IMP作了大量的insert
(2)、IMP時候創建索引通常是logging的,產生了大量的undo和redo
2、imp tunning
(1)、系統級別的調整
①、創建和使用一個大的回滾段,其大小相當於所要搬移的最大的那張Table的50%就足夠了,同時將其他回滾段offline掉,在執行import之前將資料庫置於NOARCHIVELOG模式。這將減少創建和管理archive日誌的時間;
②、創建幾個大的重做日誌檔(redo log file),刪除一些小的重做日誌檔。增加重做日誌的大小,以減少log switch的次數,也就是減少checkpoint次數,減少寫磁片的次數;
③、儘量將回滾段、datafile和redo log file分佈在不同的硬碟上。這樣可以減少I/O衝突的可能性。
④、如果要往已經存在的表中追加資料,那麼有些情況下,比如表中存在點陣圖索引,那麼最好先刪除索引,再導入。否則更新索引時會產生大量等待;
⑤、修改SQLNET.ORA,增加一行: TRACE_LEVEL_CLIENT = OFF
(2)、初始化參數文件的調整
①、增加log_buffer,採用一個大的BUFFER,以一次讀進更大的值,這個值要視系統活動狀況、資料庫大小等情況而定。通常1~3M就夠了,但是若有足夠的記憶體這個值還可更大些。同樣,我們可以查看頁面和交換的情況來確定這個值是否太大。這將減少import進程到檔中讀取資料的次數(每次它將讀取一個buffer大小的資料)。
②、將LOG_CHECKPOINT_INTERVAL的值設為大於重做日誌檔的大小或者無窮大。這樣可以將檢查點checkpoint)減小到最少或僅在日誌切換時執行。
③、增大SORT_AREA_SIZE的值,以加快排序速度;如果應用到PGA,則增加PGA的大小,可視情況設定為50M~100M,這種增加取決於機器中其他活動進程的狀況以及還有多少可用的空閒記憶體
④、增加Share_pool_size到足夠大,比如600M,然後清空共用池ALTER SYSTEM FLUSH SHARED_POOL,可以動態修改該參數,下面的方法在重啟Database後會還原到修改前的狀態,先在Sqlplus上咝?/span>$ORACLE_HOME/rdbms/admin/dbmspool.sql後,再執行 exec dbms_shared_pool.sizes(600);即可
(3)、Imp命令行中參數的應用
①、置INDEXES=N。這將加快導入無索引表的速度。但是主鍵對應的唯一索引將無條件恢復,這是為了保證資料的完整性。
②、Feedback=X, 每X筆資料顯示一次進度,可實時檢查imp進度,並且能估算imp時間
③、Ignore=Y,忽略創建及違反約束等的錯誤, Oracle不執行CREATE TABLE語句,同時也不會將資料插入到表中,而是忽略該表的錯誤,繼續恢復下一個表如果第一次導入一部分數據後,如果中途失敗,並且該表存在PK,建議truncate掉重新imp
④、RECORDLENGTH=65536,IO 記錄的長度,Max_Value=64K
⑤、COMMIT=N。這將使得import在每個物件(如table)結束之後提交(commit),而非緩衝區滿提交。這就是為什麼需要一個大的rollback段。同時如果imp失敗,可以減少很多麻煩
(4)、其它應用情況
①、通過第三方工具,如PL/SQL、TOAD、SQL Explorer等,導出創建執行資料搬移對象的腳本,以便資料導入完成後,執行重建。
②、Create table時,修改initial的值至足夠大,如1000M~2000M
Eg:Create table (column1 type,…. Initial 2000M….);
③、Create index時,可以實現多CPU和並行查詢PQO(Parallel Query Option)方式的利用。
Eg:Create index (…) parallel 5;
I、儘量利用多個CPU處理器來執行事務處理和查詢
CPU的快速發展使得ORACLE越來越重視對多CPU的並行技術的應用,一個資料庫的訪問工作可以用多個CPU相互配合來完成,加上分散式計算已經相當普遍,只要可能,應該將資料庫伺服器和應用程式的CPU請求分開,或將CPU請求從一個伺服器移到另一個伺服器。對於多CPU系統儘量採用Parallel Query Option(PQO,並行查詢選項)方式進行資料庫操作。
II、使用Parallel Query Option(PQO,並行查詢選擇)方式進行資料查詢
使用PQO方式不僅可以在多個CPU間分配SQL語句的請求處理,當所查詢的資料處於不同的磁片時,一個個獨立的進程可以同時進行資料讀取。
(5)、小結
①、調優所做過的修改,在IMP操作完成後,應當及時恢複,確保不會影響到其他session 的執行。
②、以後執行資料搬移,可以參考本報告;
六、附件(本次資料搬移資料量統計表)
Reference:
@Note:30506.1 -- Import Performance Tuning
@Note:41922.1 -- Speeding Up Import
Note 93763.1 at Metalink