麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 數據庫 > DB2 > 正文

DB2中提高Insert性能的技巧

2024-09-06 23:57:57
字體:
來源:轉載
供稿:網友

本文詳細地講述了DB2數據庫中對INSERT語句性能優化的過程。

1、INSERT的執行步驟。

這些步驟中的每一步都有優化的潛力,對此我們在后面會一一討論。

(1)在客戶機準備語句。對于動態 SQL,在語句執行前就要做這一步,此處的性能是很重要的;對于靜態 SQL,這一步的性能實際上關系不大,因為語句的準備是事先完成的。

(2)在客戶機,將要插入的行的各個 列值組裝起來,發送到 DB2 服務器。

(3)DB2 服務器確定將這一行插入到哪一頁中。

(4)DB2 在 用于該頁的緩沖池中預留一個位置。如果 DB2 選定的是一個已有的頁,那么就需要讀磁盤;如果使用一個新頁,則要在表空間(如果是SMS,也就是系統管理存儲的表空間)中為該頁物理地分配空間。插入了新行的每一頁最后都要從緩沖池寫入到磁盤。

(5)在目標頁中對該行進行格式化,并獲得該行上的一個X(exclusive,獨占的) 行鎖。

(6)將反映該 insert 的一條記錄寫入到日志緩沖區中。

(7)最后提交包含該 insert 的事務,如果這時日志緩沖區中的記錄還沒有被寫入日志文件的話,則將這些記錄寫到日志文件中。

此外,還可能發生很多類型的附加處理,這取決于數據庫配置,例如,索引或觸發器的存在。這種額外的處理對于性能來說也是意義重大的,我們在后面會討論到。

2、insert 的替代方案

在詳細討論 insert 的優化之前,讓我們先考慮一下 insert 的兩種替代方案:load 和 import。import 實用程序實際上是 SQL INSERT 的一個前端,但它的某些功能對于您來說也是有用的。load 也有一些有用的額外功能,但是我們使用 load 而不使用 insert 的主要原因是可以提高性能。

(1)load 直接格式化數據頁,而避免了由于插入導致的對每一行進行處理的大部分開銷(例如,日志記錄在這里實際上是消除了)。而且,load 可以更好地利用多處理器機器上的并行性。在 V8 load 中有兩個新功能,它們對于 load 成為 insert 的替代方案有著特別的功效,這兩個功能是:從游標裝載和從調用層接口(CLI)應用程序裝載。

(2)從游標裝載

這種方法可用于應用程序的程序代碼(通過 db2Load API),或用于 DB2 腳本。下面是后一種情況的一個例子:

以下是代碼片段:
declare staffcursor cursor forselect * from staff;
  load from staffcursor of cursor insert into myschema.new_staff;

這兩行可以用下面一行替代:

以下是代碼片段:
insert into myschema.new_staff select * from staff

同等效的 INSERT ... SELECT 語句相比,從游標裝載幾乎可以提高 20% 的性能。

(3)從 CLI 裝載

這種方法顯然只限于調用層接口(CLI)應用程序,但是它非常快。這種技巧非常類似于數組插入,DB2 附帶了這樣的示例,使用 load 時的速度是使用經過完全優化的數組插入時的兩倍,幾乎要比未經優化的數組插入快 10 倍。

3、所有 insert 可以改進的地方

讓我們看看插入處理的一些必要步驟,以及我們可以用來優化這些步驟的技巧。

(1) 語句準備

作為一條 SQL 語句,INSERT 語句在執行之前必須由 DB2 進行編譯。這一步驟可以自動發生(例如在 CLP 中,或者在一次 CLI SQLExecDirect 調用中),也可以顯式地進行(例如,通過一條 SQL Prepare、CLI SQLPrepare 或 JDBC prepareStatement 語句)。該編譯過程牽涉到授權檢查、優化,以及將語句轉化為可執行格式時所需的其他一些活動。在編譯語句時,語句的訪問計劃被存儲在包緩存中。

如果重復地執行相同的 INSERT 語句,則該語句的訪問計劃(通常)會進入到包緩存中,這樣就免除了編譯的開銷。然而,如果 insert 語句對于每一行有不同的值,那么每一條語句都將被看成是惟一的,必須單獨地進行編譯。因此,將像下面這樣的重復語句:

以下是代碼片段:
insert into mytable values (1, 'abc')
  insert into mytable values (2, 'def')

等等,換成帶有參數標記的語句,一次準備,重復執行,這樣做是十分可取的:

以下是代碼片段:
insert into mytable values (?, ?)

使用參數標記可以讓一系列的 insert 的運行速度提高數倍。(在靜態 SQL 程序中使用主機變量也可以獲得類似的好處。)

(2)發送列值到服務器

可以歸為這一類的優化技巧有好幾種。最重要的一種技巧是在每條 insert 語句中包括多行,這樣就可以避免對于每一行都進行客戶機-服務器通信,同時也減少了 DB2 開銷。可用于多行插入的技巧有:

在 VALUES 子句中包含多行的內容。例如,下面的語句將插入三行:INSERT INTO mytable VALUES (1, 'abc'), (2, 'def'), (3, 'ghi')

在 CLI 中使用數組插入(array insert)。這需要準備一條帶參數標記的 INSERT 語句,定義一個用于存儲要插入的值的數組,將該數組綁定到參數標記,以及對于每個數組中的一組內容執行一次 insert。而且,示例程序 sqllib/samples/cli/tbload.c 提供了數組插入的基本框架(但是執行的是 CLI LOAD)。從不使用數組改為使用包含 100 行的數組,可以將時間縮短大約 2.5 倍。所以應該盡可能地使用包含至少 100 行的數組。

在 JDBC 中使用批處理操作。這跟 CLI 中的數組插入一樣,基于相同的概念,但是實現細節有所不同。當通過 prepareStatement 方法準備了 insert 語句之后,剩下的步驟是針對每一列調用適當的 setXXXX 方法(例如,setString 或 setInt),然后是 addBatch。對于要插入的每一行,都要重復這些步驟,然后調用 executeBatch 來執行插入。要查看這方面的例子,請參閱“參考資料”一節中的 JDBC Tutorial。

使用 load 將數據快速地裝入到一個 staging 表中,然后使用 INSERT ... SELECT 填充主表。(通過這種方法節省下來的代價源于 load 的速度非常快,再加上 INSERT ... SELECT 是在 DB2 內(在服務器上)傳輸數據的,從而消除了通信上的代價。一般情況下我們不會使用這種方法,除非在 INSERT ... SELECT 中還要另外做 load 無法完成的處理。

如果不可能在一條 insert 語句中傳遞多行,那么最好是將多條 insert 語句組成一組,將它們一起從客戶機傳遞到服務器。(不過,這意味著每條 insert 都包含不同的值,都需要準備,因而其性能實際上要比使用參數標記情況下的性能更差一些。)將多條語句組合成一條語句可以通過 Compound SQL 來實現:

在 SQL 中,復合語句是通過 BEGIN ATOMIC 或 BEGIN COMPOUND 語句創建的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: omofun 动漫在线观看 | 国产精品一区二区手机在线观看 | 久久成年网站 | www.54271.com | 国产国语毛片 | 欧美成人性生活 | 久久9999久久| 中国黄色一级生活片 | 日韩黄色成人 | av电影在线免费 | 日本高清无遮挡 | 黄色午夜剧场 | 一级毛片真人免费播放视频 | 国av在线 | 日韩精品网站在线观看 | 日本视频在线免费观看 | 亚洲一区二区免费视频 | 国产亚洲精品久久久久婷婷瑜伽 | 国产日韩一区二区三区在线观看 | 国产一级免费片 | 国产亚洲精品久久久久久久 | 曰批全过程40分钟免费视频多人 | 视频一区 在线 | 久久小视频 | 好吊色欧美一区二区三区四区 | 色视频在线观看 | 日本在线播放一区二区 | 在线看小早川怜子av | 亚洲最新色| 国产午夜精品视频免费不卡69堂 | 成人毛片100部免费观看 | 精品在线免费播放 | 欧美亚洲国产日韩 | 国产精彩视频在线 | 国产午夜免费视频 | 久久成年网 | 男人久久天堂 | 92看片淫黄大片欧美看国产片 | 久久久成人999亚洲区美女 | 亚洲精品欧美二区三区中文字幕 | 337p日本欧洲亚洲大胆精蜜臀 |