亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Oracle > 正文

[Oracle]探討數據庫的數據導入方法

2024-08-29 13:50:23
字體:
來源:轉載
供稿:網友
每個數據庫治理員都會面臨數據導入的問題,這有可能發生在數據庫的新老移植過程中,或者是在數據庫崩潰后的恢復重建過程中,還有可能是在創建測試數據庫的模擬環境過程中,總之作為一名合格的數據庫治理員,你應該做好接受各種數據導入請求的技術儲備,同時還要盡量滿足人本能的對導入速度的苛求。本文僅針對 Oracle 數據庫所提供的加速數據導入的各種特性和技術進行探討,其中的一些方法也可以轉化應用于其他數據庫。以下七種數據導入方法哪個最適用需要針對具體情況具體分析,我也附帶列舉了影響導入速度的各種因素供斟酌。為了比較各種數據導入方法的效果,我創建了示例表和數據集,并用各種方法導入示例數據集來計算總體導入時間和導入進程占用 CPU 時間,這里得出的時間僅供參考。需要說明的是,建議你使用 Oracle 9i 企業版數據庫,當然你也可以嘗試使用 Oracle 7.3 以上的標準版數據庫。本文使用的機器配置為:CPU Intel P4,內存 256M,數據庫 Oracle 9i 企業版。
    示例表結構和數據集
    為了演示和比較各種數據導入方法,我假定數據導入任務是將外部文件數據導入到 Oracle 數據庫的CALLS表中,外部數據文件包含十萬條呼叫中心記錄,將近 6MB 的文件大小,具體的數據示例如下:
823022843842003-04-18:13:18:585001投訴手機三包維修質量
823022843852003-04-18:13:18:593352咨詢供水熱線的號碼
823022843862003-04-18:13:19:013142建議增設公交線路
    接受導入數據的表名是 CALLS,表結構如下:
NameNull?TypeComment
CALL_ID NOT NULLNUMBERPRimary key
CALL_DATENOT NULLDATENon-unique index
EMP_IDNOT NULLNUMBER 
CALL_TYPENOT NULLVARCHAR2(12) 
DETAILSNOT NULLVARCHAR2(25) 
    逐條數據插入INSERT
    數據導入的最簡單方法就是編寫 INSERT 語句,將數據逐條插入數據庫。這種方法只適合導入少量數據,如 SQL*Plus 腳本創建某個表的種子數據。該方法的最大缺點就是導入速度緩慢,占用了大量的 CPU 處理時間,不適合大批量數據的導入;而其主要優點就是導入構思簡單又有修改完善的彈性,不需要多做其它的預備就可以使用。假如你有很多時間沒法打發,又想折磨一下數據庫和 CPU,那這種方法正適合你。:)
    為了與其它方法做比較,現將十萬條記錄通過此方法導入到 CALLS 表中,總共消耗 172 秒,其中導入進程占用 CPU 時間為 52 秒。
    逐條數據插入 INSERT,表暫無索引
    為什么上一種方法占用了較多的 CPU 處理時間,要害是 CALLS 表中已創建了索引,當一條數據插入到表中時,Oracle 需要判別新數據與老數據在索引方面是否有沖突,同時要更新表中的所有索引,重復更新索引會消耗一定的時間。因此提高導入速度的好辦法就是在創建表時先不創建索引或者在導入數據之前刪除所有索引,在外部文件數據逐條插入到表中后再統一創建表的索引。這樣導入速度會提高,同時創建的索引也很緊湊而有效,這一原則同樣適用于位圖索引(Bitmap Index)。對于主要的和唯一的要害約束(key constraints),可以使之先暫時失效(disabling)或者刪除約束來獲得同樣的效果,當然這些做法會對已經存在的表的外鍵約束產生相關的影響,在刪除前需要通盤斟酌。
    需要說明的是,這種方法在表中已存在很多數據的情況下不太合適。例如表中已有九千萬條數據,而此時需要追加插入一千萬條數據,實際導入數據節省的時間將會被重新創建一億條數據的索引所消耗殆盡,這是我們不希望得到的結果。但是,假如要導入數據的表是空的或導入的數據量比已有的數據量要大得多,那么導入數據節省的時間將會少量用于重新創建索引,這時該方法才可以考慮使用。
    加快索引創建是另一個需要考慮的問題。為了減少索引創建中排序的工作時間,可以在當前會話中增加 SORT_AREA_SIZE 參數的大小,該參數答應當前會話在內存的索引創建過程中執行更多的排序操作。同樣還可以使用 NOLOGGING 要害字來減少因創建索引而生成的 REDO 日志量,NOLOGGING 要害字會對數據庫的恢復和 Standby 備用數據庫產生明顯的影響,所以在使用之前要仔細斟酌,到底是速度優先還是穩定優先。
    運用這種方法,先刪除 CALLS 表的主鍵和不唯一的索引,然后逐條導入數據,完成后重新創建索引( 表在導入數據前是空的)。該方法總共消耗 130 秒,包括重建索引的時間,其中導入進程占用 CPU 時間為 35秒。
    這種方法的優點是可以加快導入的速度并使索引更加緊湊有效;缺點是缺乏通用性,當你對表增加新的復雜的模式元素(索引、外鍵等)時你需要添加代碼、修改導入執行程序。另外針對 7*24 在線要求的數據庫在線導入操作時,刪除表的索引會對在線用戶的查詢有很大的性能影響,同時也要考慮,主要或唯一的要害約束條件的刪除或失效可能會影響到引用它們的外鍵的使用。
    批量插入,表暫無索引
    在Oracle V6 中 OCI 編程接口加入了數組接口特性。數組操作答應導入程序讀取外部文件數據并解析后,向數據庫提交SQL語句,批量插入 SQL 語句檢索出的數據。Oracle 僅需要執行一次 SQL 語句,然后在內存中批量解析提供的數據。批量導入操作比逐行插入重復操作更有效率,這是因為只需一次解析 SQL 語句,一些數據綁訂操作以及程序與數據庫之間往返的操作都顯著減少,而且數據庫對每一條數據的操作都是重復可知的,這給數據庫提供了優化執行的可能。其優點是數據導入的總體時間明顯減少,非凡是進程占用 CPU 的時間。
    需要提醒的是,通過 OCI 接口確實可以執行數據批量導入操作,但是許多工具和腳本語言卻不支持使用此功能。假如要使用該方法,需要研究你所使用的開發工具是否支持 OCI 批量操作功能。導入程序需要進行復雜的編碼并可能存在錯誤的風險,缺乏一定的彈性。
    運用上述方法,程序將外部數據提取到內存中的數組里,并執行批量插入操作(100行/次),保留了表的刪除/重建索引操作,總的導入時間下降到 14 秒,而進程占用 CPU 的時間下降到7秒,可見實際導入數據所花費的時間顯著下降了 95%。
    CREATE TABLE AS SELECT,使用Oracle9i的External Table
    Oracle 9i 的一項新特性就是 External Table,它就象通常的數據庫表一樣,擁有字段和數據類型約束,并且可以查詢,但是表中的數據卻不存儲在數據庫中,而是在與數據庫相關聯的普通外部文件里。當你查詢 External Table 時,Oracle 將解析該文件并返回符合條件的數據,就象該數據存儲在數據庫表中一樣。
    需要注重的是,你可以在查詢語句中將 External Table 與數據庫中其他表進行連接(Join),但是不能給 External Table 加上索引,并且不能插入/更新/刪除數據,究竟它不是真正的數據庫表。另外,假如與數據庫相關聯的外部文件被改變或者被刪除,這會影響到 External Table 返回查詢結果,所以在變動前要先跟數據庫打招呼。
    這種方法為導入數據打開了新的一扇門。你可以很輕易的將外部文件與數據庫相關聯,并且在數據庫中創建對應的 External Table,然后就可以立即查詢數據,就象外部數據已經導入到數據庫表中一樣。唯一的不足需要明確,數據并未真正導入到數據庫中,當外部文件被刪除或覆蓋時,數據庫將不能訪問 External Table 里的數據,而且索引沒有被創建,訪問數據速度將有所緩慢。創建 CALLS_EXTERNAL(External Table表)如下,使之與外部數據文件關聯:
 
CREATE TABLE calls_external
        (call_id    NUMBER,
         call_date  DATE,
         emp_id     NUMBER,
         call_type  VARCHAR2(12),
         details    VARCHAR2(25))
        ORGANIZATION EXTERNAL
        ( TYPE oracle_loader
        DEFAULT DirectorY extract_files_dir
        access PARAMETERS
          ( 
         RECORDS DELIMITED BY NEWLINE
          FIELDS TERMINATED BY ','
          MISSING FIELD VALUES ARE NULL
            (
            call_id, call_date CHAR DATE_FORMAT DATE MASK
            "yyyy-mm-dd:hh24:mi:ss",
            emp_id, call_type, details
            ) 
         ) 
       LOCATION ('calls.dat')
        );

      然后將 External Table 與真正被使用的表 CALLS 關聯同步,刪除 CALLS 表并重建它:
   CREATE TABLE calls
        ( 
       call_id
    NUMBER  NOT NULL,
        call_date  DATE   NOT NULL, 
       emp_id    NUMBER  NOT NULL,
        call_type  VARCHAR2(12) NOT NULL,
        details  VARCHAR2(25)
        ) 
       TABLESPACE tbs1 NOLOGGING 
       AS
        SELECT call_id, call_date, emp_id, call_type, details
        FROM   calls_external;

    因為 CALLS 表是真正的數據庫表,可以創建索引來加快訪問,表中的數據將被保留,即使外部數據文件被更新或被刪除。在建表語句中NOLOGGING要害字用于加快索引重建。

    運用這種方法導入數據,總的導入時間為 15 秒,進程占用 CPU 的時間為8秒,這比前一種方法稍微慢些,但不能就此認為使用 External Table 導入數據一定比 OCI 批量插入慢。

    這種方法的優點是,未經進行大量的編寫代碼就取得了不錯的結果,不象 OCI 批量插入存在編碼錯誤風險,它還可以使用 dbms_job 包調度數據導入進程,實現數據導入的自動化。其缺點是目標表必須先刪除后重建,假如只需要導入增量數據時此方法就不合適了,另外用戶在表的重建過程中訪問數據時會碰到 "table or view does not exist" 的錯誤,它僅適用于 Oracle 9i 以上版本的數據庫。

    INSERT Append as SELECT,使用 Oracle9i 的 External Table

    上一種方法演示了如何創建與外部數據文件關聯的數據庫表,其表的數據是由外部數據文件映射過來。缺點是數據庫表需要被先刪除再重建來保持與外部數據文件的一致和同步,對導入增量的數據而不需要刪除已有數據的情況不合適。針對這種需求,Oracle 提供了 INSERT 語句外帶 APPEND 提示來滿足。
 
   INSERT /*+ APPEND */ INTO calls (call_id, call_date, emp_id, call_type, details) SELECT call_id, call_date, emp_id, call_type, details  FROM calls_external;

    該語句讀取引用外部數據文件的 CALLS_EXTERNAL 表中內容,并將之增加到表 CALLS 中。Append 提示告訴 Oracle 使用快速機制來插入數據,同時可以配合使用表的 NOLOGGING 要害字。
    可以預見這種方法與前一方法消耗了相同的時間,究竟它們是使用 External Table 特性導入數據的不同階段解決方法。假如目標表不是空的,那將會消耗稍微長的時間(因為要重建更長的索引),而前一 CREATE TABLE as SELECT 方法是整體創建索引。
    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  callsEXCHANGE  PARTITION  part_01012004 WITH  TABLE calls_tempINCLUDING  INDEXES  WITHOUT  VALIDATION;

    分區交換操作將非常快速地只更新CALLS表的數據字典,PART_01012004分區表即刻擁有CALLS_TEMP表的所有數據,而CALLS_TEMP表變為空表。假定CALLS表使用局部索引而非全局索引,上述語句中的INCLUDING INDEXES將保證分區交換包括索引的可用性,WITHOUT VALIDATION 指明不檢查交替表中數據的匹配,加快了交換的速度。
    結論
    以上探討了Oracle數據庫的多種數據導入方法,每種方法都有其優缺點和適用環境,能夠滿足你不同的導入需求,當然你需要在了解了這些方法后,在速度、簡易性、靈活性、可恢復性和數據可用性之間尋求最佳導入方案。
    為了對比各種方法的效果,我們創建了一個實例來展示各種方法的導入效率和效果,從中你可以選擇最適合的方法用于今后的數據導入工作。同時請記住,本文并未囊括所有的ORACLE數據導入技術(比如并行數據導入技術),這需要我們繼續不懈的探索和嘗試。
數據導入方法總體導入時間(秒)導入進程占用CPU時間(秒)
逐條數據插入INSERT17252
逐條數據插入INSERT,表暫無索引13035
批量插入,表暫無索引 147
Create As Select,使用Oracle9i的External Table158
INSERT Append as SELECT,使用Oracle9i的External Table158
SQL*Loader conventional path 缺省導入選項8112
SQL*Loader direct path 導入選項 93


上一篇:[Oracle]進程結構和內存結構的實例

下一篇:Oracle利用UTL_MAIL發送電子郵件

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美一级视频免费在线观看| 久久久久久久久久国产精品| 亚洲欧美在线x视频| 久久精品99久久久久久久久| 4438全国成人免费| 91精品啪在线观看麻豆免费| 日本久久久a级免费| 成人精品视频久久久久| 日韩视频免费看| 福利精品视频在线| 国产福利视频一区二区| 久久国产天堂福利天堂| 中文字幕v亚洲ⅴv天堂| 亚洲成人网久久久| 一区二区欧美日韩视频| xxxxx91麻豆| 日韩亚洲在线观看| 亚洲一二三在线| 国产精品久久久久不卡| 亚洲欧美一区二区三区四区| 欧美一区二区大胆人体摄影专业网站| 久久精品中文字幕免费mv| 亚洲精品日韩久久久| 日本中文字幕不卡免费| 国产精品成人久久久久| 8090成年在线看片午夜| 亚洲国产成人精品一区二区| 成人黄色网免费| 精品视频久久久久久久| 视频在线观看一区二区| 国产精品国产三级国产aⅴ浪潮| 亚洲精品一区在线观看香蕉| 亚洲va欧美va国产综合剧情| 中文字幕日韩av综合精品| 韩国三级日本三级少妇99| 4p变态网欧美系列| 欧美高清videos高潮hd| 久久99久久亚洲国产| 久久亚洲一区二区三区四区五区高| 国产精品一久久香蕉国产线看观看| 97精品视频在线播放| 精品久久久久久国产| 亚洲人成电影网站色| 久久久999国产精品| 日韩在线免费视频| 狠狠爱在线视频一区| 国模吧一区二区| 国产亚洲美女精品久久久| 亚洲精品日韩久久久| 高跟丝袜欧美一区| 国产精品黄页免费高清在线观看| 日韩欧美在线免费| 91在线观看免费| 欧美视频精品一区| 中文字幕欧美日韩va免费视频| 中文字幕久热精品在线视频| 精品亚洲男同gayvideo网站| 91免费视频网站| 92裸体在线视频网站| 亚洲人在线视频| 中文字幕亚洲一区二区三区五十路| 中文字幕精品在线| 亚洲免费视频观看| 欧美日韩精品在线| 国产精品爽爽爽爽爽爽在线观看| 91高清视频免费| 亚洲欧洲日产国码av系列天堂| 日韩**中文字幕毛片| 日韩欧美综合在线视频| 97在线视频免费| 欧美成人黄色小视频| 国产精品美女久久| 欧美性猛交xxxxx水多| 亚洲欧美日韩在线高清直播| 欧美视频在线看| 日韩免费av片在线观看| 国产精品久久久久久久7电影| 日本欧美爱爱爱| 视频在线观看一区二区| 九九视频直播综合网| 久久久久久久一区二区| 毛片精品免费在线观看| 亚洲成人黄色在线| 国产69精品久久久久9999| 亚洲欧美一区二区三区在线| 一区三区二区视频| 色青青草原桃花久久综合| 亚洲国产精品国自产拍av秋霞| 日韩网站免费观看高清| 国产精品美乳一区二区免费| 91chinesevideo永久地址| 国产精品欧美一区二区| 日韩有码视频在线| 日韩在线视频导航| 国产精品高潮呻吟久久av野狼| 亚洲jizzjizz日本少妇| 深夜福利日韩在线看| 国产精品香蕉av| 日韩三级成人av网| 欧美大尺度电影在线观看| 欧美日韩在线第一页| 久久全国免费视频| 欧美激情欧美狂野欧美精品| 国内精品久久久久久久| 亚洲色图激情小说| 亚洲成色777777在线观看影院| 国产69久久精品成人看| 精品色蜜蜜精品视频在线观看| 日韩一区二区精品视频| 中文字幕欧美日韩精品| 丁香五六月婷婷久久激情| 欧美另类极品videosbestfree| 亚洲aⅴ日韩av电影在线观看| 欧美日韩免费网站| 日韩欧美在线第一页| 国产在线视频2019最新视频| 久久久精品在线观看| 欧美成人亚洲成人日韩成人| 亚洲激情电影中文字幕| 国产精品国产亚洲伊人久久| 国产黑人绿帽在线第一区| 亚洲综合成人婷婷小说| 国产精品亚洲一区二区三区| 亚洲成人国产精品| 欧洲s码亚洲m码精品一区| 亚洲国产一区自拍| 亚洲网站在线看| 中文字幕在线观看亚洲| 国产精品嫩草视频| www.精品av.com| 亚洲白拍色综合图区| 国产日韩亚洲欧美| 精品国产鲁一鲁一区二区张丽| 日韩精品中文字幕在线观看| 亚洲欧美国产视频| 欧美成人免费大片| 欧美丝袜美女中出在线| 国产精品aaaa| 久久免费福利视频| 91久久精品视频| 国产精品视频免费在线| 欧美人与性动交a欧美精品| 欧美午夜www高清视频| 国产精品久久久久秋霞鲁丝| 久久福利视频网| 欧美性猛交xxxx免费看久久久| 亚洲福利视频免费观看| 欧美在线观看一区二区三区| 亚洲国产精彩中文乱码av| 欧美做受高潮电影o| 国产午夜一区二区| 97婷婷涩涩精品一区| 欧美做受高潮电影o| 国产成人久久精品| 欧美激情第1页| 国产成人综合亚洲| 亚洲成人精品久久| 日韩欧美亚洲一二三区| 亚洲欧美国产一本综合首页| 成人激情在线播放| 91精品国产网站| 视频在线一区二区| 国产日本欧美一区二区三区| 中文字幕亚洲欧美一区二区三区|