7. 空余空間方面的考慮
分配空余空間的主要目的是使數據行的物理順序與群集索引一致,以減少頻繁重組數據的需要。此外,對行的更好的群集會使讀訪問的速度更快,行插入的速度也更快。然而,過多地分配空余空間可能會產生浪費的dasd空間,導致每次i/o只能傳輸更少的數據,緩沖池的利用效率更低,并且要掃描更多的頁。
表空間和索引中空余空間的分配是由create或alter tablespace以及create或alter index語句的pctfree和freepage選項確定的。
pctfree告訴db2在裝載或重組數據時,表空間或索引中的每個頁要留出多少百分比的空余空間。如果沒有足夠的空余空間來按照恰當的順序(也就是按群集順序)編寫行或索引,那么db2就必須將多出的數據放到另一個頁上。當越來越多的記錄被亂序存放時,性能就會出現問題。
freepage告訴db2在裝載或重組數據時,應該過多久就分配一整頁的空余空間。例如,如果指定了freepage 5,那么db2將在用數據填充了5個頁之后分配一頁的空余空間。如果表行大于頁寬的一半,則應該使用freepage,因為在那樣的環境下不能在一頁上再insert一行。
是否定義帶空余空間的表空間,以及分配多少的空余空間,這很大程度上取決于表空間中表的insert特征(其次是delete活動)。換句話說,這取決于將行添加到表中的頻率,以及將行添加到表的什么地方。下面有4種類別:
2) 隨機插入:對于已經有很多行、并且insert活動的級別很低,那么一開始可以使用默認的pctfree(對于表空間,該值是5,對于索引,該值是10)。然后使用runstats監控數據失序的程度,再考慮您期望運行reorg的頻率,對pctfree進行必要的上下調整。對于insert活動級別很高的表,可能需要使用大于默認值的pctfree。對于開始為空或者只包含很少行的表(例如在新數據庫的部署期間),可能需要指定一個較高的pctfree,并不時地運行一下reorg,直到這個表被填充好為止。
3) 在表的末尾插入:如果一個表中的行的長度不會增長,那么就無需分配空余空間,因為這些行是在表的末尾插入的。由于這些行是按照物理的群集順序來寫的,因此不需要運行reorg。但是,如果一個表包含可更新的varchar列,或者該表被壓縮,那么有可能行的長度會增長,從而導致某一行被轉移到其他頁上。您可以通過對表空間執行runstats,然后檢查db2編目表sysibm.systablepart的nearindref和farindref這兩列來判斷上述情況。如果表變得缺乏組織,那么為表空間指定一個pctfree,并繼續用runstats監控位置不當(mislocated)的行。根據當前的數據以及您所觀察到的趨勢,對reorg的頻率和pctfree的數字進行相應的調整。通過在reorg tablespace中指定indreflimit和reportonly選項,可以監控被更新的db2表中位置不當的行的數目,以及隔多遠會出現這樣的行。
4) 在熱點(hot spot)中插入:在這種情況下,表上的插入活動很頻繁,而且集中在某一個位置(或幾個位置),而不是在表的末尾進行插入。這一類情況可能是最難于處理的。可以嘗試增加pctfree的值。如果插入活動停留在主段(home segment)中,并且插入的行不是很長,那么可以將數行存儲在相同的頁中。在此情況下,另一種可以考慮的方案是使用freepage。這時有必要嚴密監控表變得無組織的速度,這樣就可以在性能急劇下。
五、索引設計方面的考慮
索引也是一種db2對象(一個單獨的vsam數據集),它由一組排好序的鍵組成,這些鍵是從相應表中的一個列或多個列抽取出來的。很多db2專家聲稱,只有為表空間建立恰當的索引,才是使得訪問該表空間中db2數據的應用程序的性能達到最佳、最有效的效果。數年前,在i/t中dasd的成本和空間是更重要的考慮因素。隨著技術的發展,通過增加更多的索引(或添加列到已有的索引中)來減少i/o,以及由此消耗的額外磁盤空間,這幾年兩者之間的權衡已經變得越來越有吸引力。索引所帶來的主要性能好處是:
1) 提供指向表中被請求的數據行的直接指針。
2) 如果結果集要求的順序與索引一致,則可以消除排序。
3) 如果被請求的列都包含在索引項中,則可以避免不得不讀數據行的情況。
1. 分區索引
在db2 udb v7中創建分區的表空間時,db2根據create index語句的part子句將數據劃分到幾個分區上。那樣的索引就成為所謂的分區索引,而這種分區的方法就被稱為 索引控制的分區(index-controlled partitioning)。對于分區索引,建議選擇不大可能改變的鍵列。如果對那些列進行更新,則可能導致一行從一個分區轉移到另一個分區,從而降低了性能。
db2 v8一個重要的特性是表控制的分區(table-controlled partitioning)。這時,當創建分區的表時,分區的邊界由create table語句決定,而不是由create index語句決定。對于索引控制的分區方法,分區的表、分區索引和群集這幾個概念之間有點糾纏不清。而在表控制的分區方法中,這三個概念是各自獨立的。這種增加的靈活性使您可以考慮更多潛在的設計方案,因而也增加了提高db2數據庫及其應用程序性能的機會。
2. 何時建立索引
create index語句使用戶可以立即建立索引,或者將索引的建立推遲到方便的時候。如果立即建立索引,則需要掃描表空間,這樣要花費比較多的時間。通過指定defer,則可以推遲索引的創建。
只要有可能,應該在初次裝載一個表之前創建其所有索引,因為load實用程序建立索引的效率比create index過程要高。如果需要在一個已有的(并且被填充的)表上創建一個索引,那么可以使用defer子句。然后可以在晚些時候使用rebuild index實用程序,這個實用程序與load實用程序一樣,是更為有效的填充索引的方式。
3. piecesize
db2 udb v5中引入了一個新特性,這種特性使您可以將一個非分區索引(non-partitioning index,npi)拆成數塊,然后控制將組成索引空間的多個數據集的大小。通過使用這些小塊,可以使npi的索引頁散步到多個數據集中。
通過在create或alter index語句中指定關鍵字piecesize,可以確定各塊的大小。piecesize的值必須是2的冪,其大小可以介于256kb到64gb之間。對于常規表空間,piecesize的默認值是2gb,對于large表空間,默認值是4gb。如果npi極有可能顯著增長,那么應選擇一個更大的值。在為主空間和輔助空間(create index語句的priqty和secqty選項)的分配確定值時,也應該留意piecesize的值。
通過使用這個選項,可以促進并行性,從而提高npi的掃描性能。另一個好處是可以減少在讀或更新的處理過程中對i/o的爭用。通過指定一個較小的piecesize,可以創建更多的塊,從而對塊的放置有更多的控制。將這些塊放在不同的i/o路徑中,可以減少訪問npi所需的sql操作的爭用。
4. 理想的索引
通過檢查應用程序中的sql語句,可以建立一種想象起來很好的索引。
1) 首先,在索引中包括where子句中的所有列,這樣,就可以使用索引形成的屏蔽來拒絕結果集中不合格的行。將這些列放在索引的開始部分。這樣一來,當對sql語句進行explain時,就可以產生最大的matchcols值。
2) 接下來,確保索引中這些列有適當的順序(按照order by子句),這樣可以避免排序。在進行explain時,通過檢查plan_table中所有不同的sort*列,便可以確認這一點。
3) 最后,如果可能的話,將select中所有的列包括到索引當中,這樣就不需要訪問表中的行。這樣的索引項可以提供所有被請求的數據。這在explain中就表現為indexonly = y。
在很多情況下,實現這一理想的代價太高,也不切實際,甚至是不可能的。對于一個索引中可以包括的列數,以及整個索引項的長度,都有架構上的限制(雖然這些限制已考慮到相當大的索引項長度和靈活性)。而且,也要考慮索引維護的成本。雖然建立理想化的索引可以顯著提高查詢性能,但是每當對db2數據庫執行sql寫操作(insert、update 或 delete)時,上述理想化的索引都會有負面的影響。因此,您常常可以選擇實現只包括在where和order by子句中引用到的列的索引。
六、并行處理方面的考慮
這些年,db2通過實現各種并行處理的方法,已經大大提高了訪問數據的性能。為了提高數據密集型只讀查詢的性能,db2 v3引入了查詢i/o并行。在這種并行中,db2充分利用分區表空間促成的可用i/o帶寬。通過這種方法,db2可以為單個i/o請求啟動多個并發的i/o請求,并在多個數據分區上執行并行i/o處理。這通常可以顯著減少i/o bound查詢所需的時間,而代價只是稍微增加的cpu時間。
db2 v4引入了另一種并行技術,這種技術稱作查詢cp并行。這種方法將并行處理擴展到過程密集型(process-intensive)查詢中來。通過這種方法,一條查詢可以使db2生成多個任務,這些任務被并行地執行,以訪問數據。分區表空間最能體現這種并行所帶來的性能提高。
db2 udb v5引入了sysplex查詢并行,進一步擴展了并行處理。cp并行可以在db2子系統中為一條查詢使用多個任務,而sysplex查詢并行這種方法使一個db2數據共享組中的所有成員可以一起處理一個查詢。對于那些主要是只讀形式的i/o密集型和處理器密集型查詢,都可以從這種并行中得到好處。
1. 支持并行訪問
db2環境中對并行的支持有一個度的問題。首先,在db2子系統級,并行訪問是在安裝面板dsntip4上控制的。dsntip4上的max degree選項決定了最大并行度(并行任務的最大數量)。默認值是0,這意味著對于db2可能調用的并行度沒有上限。我建議您先估計z/os環境中的虛擬存儲能力和局限性,這樣db2就不至于創建多于虛擬存儲所能處理的并行任務。
您可以通過bind plan和bind package命令的degree選項來控制db2是否利用并行處理。若指定degree(1),表示禁止并行處理,若指定degree(any),則表示支持并行處理。為獲得更大的靈活性,動態sql允許通過set current degree語句在一個計劃或包中更改這個選項,該語句可以控制專用寄存器中的值。
當一個計劃或包與degree(any)捆綁在一起,或者current degree寄存器被設為any時,db2優化器將考慮對于最有效的順序計劃,并行是否可行。如果并行不可行,那么就選擇次好的順序計劃。
2. 限定分區掃描
限定分區掃描允許db2將數據掃描限制在一個分區表空間中。根據sql謂詞中的值,db2可以判斷可能包含sql語句所請求的表行的最低分區和最高分區,然后將數據掃描限制在這一范圍內的分區中。為了使用這種技術,sql必須提供分區索引的第一個鍵列上的一個謂詞。
3. 并行方面的建議
為了進一步促進并行處理所能帶來的性能提高,下面列出了一些需要考慮的事情:
1)盡可能均勻地對表空間分區,因為數據不整齊會對并行度產生影響。一般來說,db2根據最大物理分區的大小將表空間分成邏輯上的幾塊。
2) 為db2應用程序的處理分配盡可能多的中央處理器(central processor,cp),以及盡可能多的 i/o 設備和路徑。
3) 對于i/o密集型查詢,應確保分區的數量與可以訪問該表空間的i/o路徑的數量一致。
4) 對于處理器密集型查詢,應確保分區的數量等于將被分配用來在數據共享組上處理查詢的cp的數量。
5) 將用于表空間和索引的分區放在單獨的dasd卷中,并且,如果可能的話,要隔開控制單元,以減少i/o爭用。
6) 按時執行runstats實用程序,以獲得分區級的統計信息。
7) 監控虛擬緩沖池的閾值和使用情況,確保提供了足夠的緩沖池空間來最大化并行度。
七、緩沖池方面的考慮
1. 緩沖池的重要性
很多專家將數據庫緩沖池看作db2環境中影響性能的最關鍵的資源。很多db2的架構和設計,其基本思想都是盡可能地避免物理i/o。
db2緩沖池由數個插槽(slot)的連續的內存組成。數據和索引頁被從dasd中讀出之后,便進入這些插槽,并留在其中,直到db2緩沖區管理器確定那些插槽要用于其他數據。應用程序所請求的數據出現在內存中(而不是外面的dasd上)的概率越大,總體性能就越好。實際上,這里的數據被重復使用,因而減少了應用程序對i/o的需要。
是否釋放一個緩沖池槽,這是根據最近被使用(lru)原則來決定的。db2維護兩個lru列表,一個用于被隨機訪問的頁,另一個用于被順序訪問的頁。這樣可以防止大規模的表掃描完全支配緩沖池,并惡劣地影響隨機操作。通過使用不同的閾值,db2 提供了改善緩沖池性能的靈活性。在db2 sql reference手冊的第2.7.4節中對這些閾值進行了較為詳細的討論。
2. 為緩沖池設置適當的大小
緩沖池大小的指定要取決于可用存儲(包括中央存儲和擴展存儲)的容量。我建議首先分析緩沖池的分配,然后逐漸增加緩沖池的大小,直到通過增加分配的空間已無法增加更多的吞吐量,或者直到mvs換頁率已難于接受為止。為實現這一點,要使dasd i/o的數量持續下降,并不斷增加vpsize,直到換頁的成本超出了通過減少i/o所帶來的好處為止。
早些時候,getpages的數量被認為可能是對db2正在運行的工作量的最好度量。緩沖池的目的是減少i/o(異步讀通常表明需要進行預取,從性能角度來看,這樣做通常是值得的。另一方面,同步讀常常需要對dasd進行隨機i/o,因為被請求的頁不在緩沖池中)。會計報表顯示對應于每個緩沖池的getpages和同步讀的數量。一個被普遍接受的rot聲稱,如果getpages對同步讀的比率小于10:1,那么應該估計對更大緩沖池的需要。
3. 多緩沖池配置
如果操作系統允許為db2緩沖池分配相當大的內存,那么使用多緩沖池的配置很可能可以提高特定應用程序或數據庫的性能。然而,需要清楚的是,若有了多個緩沖池,那么對這些緩沖池使用效率的監控就變得更加重要。
下面給出了關于分配多個緩沖池的一般建議:
1) 將表空間與和它們相關的索引分放到不同的緩沖池中,以減少索引i/o。
2) 將有不同數據訪問模式的數據統一放到不同的緩沖池中。批處理和查詢應用程序通常要進行大量的順序處理,而用于oltp的數據訪問往往更具有隨機性。這為利用各種閾值處理緩沖池中某些類型的數據訪問提供了一種方法。
3) 為獨立的應用程序提供一個單獨的緩沖池。這就為緊密監控應用程序的性能問題或測試新的應用程序提供了一種方法。
4) 如果排序的性能在您的環境中很重要,那么需要為工作文件創建一個單獨的緩沖池。
5) 對于相對較小但更新頻繁的表,通過一個足夠大的單獨的緩沖池,也許可以同時減少讀和寫的i/o。
6) 為只讀表(小的引用表)提供單獨的緩沖池可以提高性能。
八、結束語
考慮周詳的數據庫設計可以提供巨大的性能收益,但是這必須在應用程序開發過程的早期便開始著手。從早期的db2開始,明智的開發人員就已經使用了前面提到的很多準則,這些準則直到現在也仍然成立。但是,db2功能的增強、其他領域中硬件和軟件技術的變化將影響當前和將來的應用程序,知道這一點至關重要。當數據庫性能成為開發過程中的焦點時,您的數據庫設計使得為db2應用程序提供最佳性能有了更大的可能性。