優化Oracle庫表設計的若干方法 一

2022-09-16 20:36:17 字數 2747 閱讀 9894

前言

絕大多數的oracle資料庫效能問題都是由於資料庫設計不合理造成的,只有少部分問題根植於database buffer、share pool、redo log buffer等記憶體模組配置不合理,i/o爭用,cpu爭用等dba職責範圍上。所以除非是面對乙個業已完成不可變更的系統,否則我們不應過多地將關注點投向記憶體、i/o、cpu等效能調整專案上,而應關注資料庫表本身的設計是否合理,庫表設計的合理性才是程式效能的真正執牛耳者。

合理的資料庫設計需要考慮以下的方面:

·業務資料以何種方式表達。如乙個員工有多個email,你可以在t_employee表中建立多個email欄位如email_1、email_2、email_3,也可以建立乙個t_email子表來儲存,甚至可以用逗號分隔開多個email位址存放在乙個欄位中。

·資料以何種方式物理儲存。如大表的分割槽,表空間的合理設計等。

·如何建立合理的資料表索引。表索引幾乎是提高資料表查詢效能最有效的方法,oracle擁有型別豐富的資料表索引型別,如何取捨選擇顯得特別重要。

本文我們將目光主要聚焦於資料表的索引上,同時也將提及其他兩點的內容。通過對乙個簡單的庫表設計例項的分析引出設計中的不足,並逐一改正。考慮到手工編寫庫表的sql指令碼原始且低效,我們將用目前最流行的庫表設計工具powerdesigner 10來講述表設計的過程,所以在本文中你還會了解到一些相關的powerdesigner的使用技巧。

乙個簡單的例子

某個開發人員著手設計乙個訂單的系統,這個系統中有兩個主要的業務表,分別是訂單基本資訊表和訂單條目表,這兩張表具有主從關係的表,其中t_order是訂單主表,而t_order_item是訂單條目表。資料庫設計人員的設計成果如圖 1所示:

圖 1 訂單主從表

order_id是訂單號,為t_order的主鍵,通過名為seq_order_id的序列產生鍵值,而item_id是t_order_item表的主鍵,通過名為seq_order_item的序列產生鍵值,t_order_item通過order_id外來鍵關聯到t_order表。

需求文件指出訂單記錄將通過以下兩種方式來查詢資料:

·client + order_date+is_shpped:根據"客戶+訂貨日期+是否發貨"條件查詢訂單及訂單條目。

·order_date+is_shipped:根據"訂貨日期+是否發貨"條件查詢訂單及訂單條目。

資料庫設計人員根據這個要求,在t_order表的client、 order_date及is_shpped三字段上建立了乙個復合索引idx_order_composite;在t_order_item為外來鍵order_id建立idx_order_item_order_id索引。

讓我們看一下該份設計的最終sql指令碼:

/*訂單表*/

create table t_order (

order_id number(10) not null,

address varchar2(100),

client varchar2(60),

order_date char(8),

is_shipped char(1),

constraint pk_t_order primary key (order_id)

);create index idx_client on t_order (

client asc,

order_date asc,

is_shipped asc);

/*訂單條目子表*/

create table t_order_item (

item_id number(10) not null,

order_id number(10),

item varchar2(20),

count number(10),

constraint pk_t_order_item primary key (item_id)

);create index idx_order_item_order_id on t_order_item (

order_id asc);

alter table t_order_item add constraint fk_t_order__reference_t_order foreign key (order_id) references t_order (order_id);

我們承認在er關係上,這份設計並不存在的缺陷,但卻存在以下有待優化的地方:

·沒有將表資料和索引資料儲存到不同的表空間中,而不加區別地將它們儲存到同一表空間裡。這樣,不但會造成i/o競爭,也為資料庫的維護工作帶來不便。

·oracle會自動為表的主鍵列建立乙個普通b-tree索引,但由於這兩張表的主鍵值都通過序列提供,具有嚴格的順序性(公升序或降序),此時手工為其指定乙個反鍵索引(reverse key index)將更加合理。

·在子表t_order_item外來鍵列order_id上建立的idx_order_item_order_id的普通b-tree索引非常適合設定為壓縮型索引,即建立乙個壓縮型的b-tree索引。因為乙份訂單會對應多個訂單條目,這就意味著t_order_item表存在許多同值的order_id列值,通過將其索引指定為壓縮型的b-tree索引,不但可以減少idx_order_item_order_id所需的儲存空間,還將提高表操作的效能。

·企圖僅通過建立乙個包含3欄位idx_order_composite復合索引滿足如前所述的兩種查詢條件方式的索引是有問題的,事實上使用order_date+is_shipped復合條件的查詢將利用不到idx_order_composite索引。

優化Oracle庫表設計的若干方法

1.oracle會自動為表的主鍵列建立索引,這個預設的索引是普通的b tree索引 2.索引本身實際上是乙個表,因此當對表新增乙個記錄時,oracle必須做兩次插入。這樣,組表增加乙個索引將導致插入操作要兩倍多的時間 兩倍的時間用於兩次插入,另外還需要一點時間處理二表之間 的同步 增加兩個索引將使用...

優化Oracle庫表設計的若干方法 一

前言 絕大多數的oracle資料庫效能問題都是由於資料庫設計不合理造成的,只有少部分問題根植於database buffer share pool redo logbuffer等記憶體模組配置不合理,i o爭用,cpu爭用等 dba職責範圍上。所以除非是面對乙個業已完成不可變更的系統,否則我們不應過...

優化Oracle庫表設計的若干方法 三

2 顯式為主鍵列建立反向鍵索引 2.1 反向鍵索引的原理和用途 我們知道oracle會自動為表的主鍵列建立索引,這個預設的索引是普通的b tree索引。對於主鍵值是按順序 遞增或遞減 加入的情況,預設的b tree索引並不理想。這是因為如果索引列的值具有嚴格順序時,隨著資料行的插入,索引樹的層級增長...