表分析、約束及表間關係

表分析
Oracle優化器簡述

  
   Oracle提供兩種優化器,CBO(Cost based Optimizer)和RBO(Ruler Based Optimizer)。CBO要求的是 最有效的方式是成本最小的訪問方法,其中成本也稱爲開銷,主要指I/O時間和CPU時間,大多數情況下,主要開銷在對磁盤的I/O的開銷。CBO的依據包括:
  
 
表分析原理
CBO要基於統計數據
l默認情況下,Oracle 11g數據庫會自動收集CBO需要的統計數據,默認的是工作日晚上10點至早上6點以及休息日全天;
l一般是自上次統計至今數據變化超過10%的表會被自動重新統計;
l如果沒有分析統計數據,則使用參數 OPTMIZER_DYNAMIC_SAMPLING的默認值,此舉往往是低效的;
 
何時需要手動統計
l易變化的表發生了刪除、清空等操作;
l表的體積發生了10%以上的增加時,但我們建議減少時也可以統計
l統計的方法是對錶進行分析,oracle會同步分析表的列、索引
 
如何查看錶是否被分析過
lSelect a.LAST_ANALYZED,a.TABLE_NAME,
  a.NUM_ROWS,a.SAMPLE_SIZE
  from dba_tables a
    where owner = 'XJGL‘  order by a.LAST_ANALYZED desc
 
如何查看自動收集統計信息的任務
lselect client_name,status from dba_autotask_client,其中client_name爲auto optimizer stats collection的即代表自動收集任務;
l而10g中通過查詢dba_scheduler_jobs視圖來查看,11g和10g的此不同點在部分11g書籍中描述是錯誤的,應以0racle官方文檔爲準。
 
 
啓用自動收集統計信息的任務
BEGIN
    DBMS_AUTO_TASK_ADMIN.ENABLE(
      client_name => 'auto optimizer stats collection',
      operation => NULL,
     window_name => NULL);
 END;
禁用自動收集統計信息的任務
 
BEGIN
    DBMS_AUTO_TASK_ADMIN.DISABLE(
      client_name => 'auto optimizer stats collection',
      operation => NULL,
     window_name => NULL);
 END;
自動收集統計信息的任務依賴於誰
l依賴於Oracle的修改監控(modification monitoring )功能,如果該功能被禁用,則自動收集統計信息的任務無法探測到失真的統計信息(stale statistics);
l只有當參數STATISTICS_LEVEL設置爲ALL或者TYPICAL時,修改監控功能纔有效,該參數的默認值是TYPICAL。
l在OEM中,選擇服務器->數據庫配置->初始化參數可查看該參數:
 
 
防止失真的統計信息
 
l修改監控的功能是跟蹤自上次收集統計信息以來,估算其所監控的表的更新操作(I、U、D)和清空操作所引起的數據變化量(10%的問題);
l我們可以使用視圖USER_TAB_ MODIFICATIONS來查詢表中數據的變化情況,但是一般情況下,該表的數據的更新會有延遲,此時可以使用DBMS_ STATS.FLUSH_DATABASE_MONITORING_INFO 從內存中立即獲取未推送的監控信息;
l收集統計數據(當數據變化超過10%時,選項設置爲GATHER _AUTO或GATHER _STALE ,示例見附件) 
 gather_database_stats   爲數據庫的所有對象收集統計數據
    gather_schema_stats    爲用戶(模式)的所有對象收集統計數據,最常用
 gather_table_stats         爲某個表及其索引收集統計數據
  gather_index_stats         爲某個索引收集統計數據
 
表分析的目的和作用
 
l收集或刪除索引或索引分區、分區表或表、索引組織表、聚簇、或標量對象屬性的統計信息;
l驗證結構索引或索引分區、表或表分區、索引組織表、聚簇、或對象的引用( REF );
l識別表、聚簇中行遷移。
針對analyze的蒐集和刪除統計信息功能而言,oracle推薦使用DBMS_STATS包來蒐集優化信息,DBMS_STATS可以並行的蒐集信息,可以蒐集分區表的全局信息,進一步來說,按成本的優化器只會使用DBMS_STATS包所統計出來的信息。使用ANALYZE在兩方面不依賴於CBO:
(1).使用VALIDATE或LIST CHAINED ROWS子句 (2)收集freelist的塊信息
 
表分析需要的權限
l模式的表分析:模式首先必須是本地的,且該模式要麼是自己的、要麼需有ANALYZE ANY系統權限
l聚簇或表的行遷移列出分析:列表對象是屬於當前模式自己的、或在列表對象上具有INSERT權限、或具有INSERT ANY TABLE系統權限。
l分區表驗證:將你分析的rowid寫入的表上具有INSERT權限,或者或具有INSERT ANY TABLE系統權限。
 
表分析語法
 
ANALYZE 
  { TABLE [ schema.]table 
      [ PARTITION ( partition ) | SUBPARTITION ( subpartition ) ] 
   | INDEX [ schema. ]index 
      [ PARTITION ( partition ) | SUBPARTITION ( subpartition ) ] 
  | CLUSTER [ schema. ]cluster 
  } 
  { COMPUTE [ SYSTEM ] STATISTICS [for_clause] 
  | ESTIMATE [ SYSTEM ] STATISTICS [for_clause][SAMPLE integer { ROWS | PERCENT }] 
  | validation_clauses 
  | LIST CHAINED ROWS [ into_clause ]
  | DELETE [ SYSTEM ] STATISTICS
 
  } ;
 
  表
 
l對指定的表進行分析,同步也會分析該表上基於函數的索引,分析的結果會放在USER_TABLES, ALL_TABLES,DBA_TABLES表
lnum_rows(行數)、*blocks(表用到的數據塊數)、*empty_blocks(分配給該表未使用的數據塊數)、ave_space(每個數據塊平均可用字節數)、chain_cnt(行遷移數)、avg_row_len(行平均字節數),帶*的表示會精確統計。
l不能分析數據字典表、外部表(可用dbms_stat)、臨時表、可變數組、嵌套表、引用以及其它對象類型;建議僅僅對自己模式下的數據表進行分析。
 
   索引
 
l對指定的索引進行分析,分析的結果會放在USER_INDEXES, ALL_INDEXES, DBA_INDEXES中
l*blevel(根節點至葉子節點的深度)、leaf_blocks(葉子節點塊數)、distinct_keys(唯一索引的數量)、avg_leaf_blocks_per_key(每個索引的平均葉子節點數)、 avg_data_blocks_per_key(每個索引的平均數據塊數) 、avg_row_len(行平均字節數),帶*的表示會精確統計。
   聚簇
 
l對指定的聚簇進行分析,分析的結果會放在USER_CLUSTERS, ALL_CLUSTERS, DBA_CLUSTERS中
l如果一定要用聚簇,請參閱相關文檔。
 
   統計
 
lCOUMPUTE全分析統計,爲CBO服務
lESTIMATE按抽樣的比例進行分析,也是爲CBO服務
 
   其它
 
lLIST CHAINED ROWS列出行遷移數據,可以使用數據庫自帶的腳本( UTLCHAIN.SQL )建立結果寫入的表CHAINED_ROWS
lDELETE表示刪除統計數據,如果不再需要統計數據時,可以使用該項,指定SYSTEM表示刪除Oracle數據庫系統的統計數據(不含用戶統計的)
 
 
方法
1.寫ANALYZE語句     2.使用TOAD工具
  
  
 
 
表分析舉例
 
  
  
 
 
約束
常用的數據完整性約束規則包括:
1.NOT NULL
2.唯一關鍵字
3.主關鍵字
4.外鍵
5.檢查項Check
 
由於本部分內容再前面的章節中已經穿插講解,本處不再贅述
 
約束條件
l使用約束的目的是爲了保持數據的完整性;
l約束條件是定義一個或多個條件的一種方法,用戶的輸入在被Oracle接收進數據表之前,必須滿足這些約束條件;
l約束條件作爲表的定義的一部分被存儲,以備將來自動執行
l不符合約束條件的數據將被Oracle中斷;
lDML中只有Insert、Update語句能觸發約束條件;
l約束數據存放在USER_CONSTRAINS、DBA_CONSTRAINS、ALL_CONSTRAINS中。
 
NULL & NOT NULL
l建立數據庫表時,字段的默認值是NULL,如果要約定非空需要指定;
l可以修改字段屬性,語法:
  ALTER TABLE table_name MODIFY(column_name NULL|NOT NULL)
但如果數據庫中已經存在數據,且該列有 null值,則修改不會成功。
唯一約束
l唯一約束禁止一個列或者聯合列的數據重複,但允許某些列爲null;
l數據庫在創建唯一約束時,強制創建或者重用列上的索引。如果列上無索引,那麼強制創建一個唯一索引,否則就重用之前的索引
l增加唯一約束語法:
  ALTER TABLE table_name ADD CONSTRAINT  constrain_name UNIQUE(column_name)
 
主鍵
l主鍵實際上是非空約束和唯一約束的組合體;
l雖然Oracle也可以通過Alter語句修改、增加主鍵,但我們還是建議先刪除,再增加;建議使用CASE工具,以避免死記語法。(語法在表間關係部分講)
 
外鍵
l外鍵是保證數據完整性的,表示數據間關係代數的關係,但不建議大量使用,而採用替代的方法;
l同主鍵,增加和修改建議使用工具。 (語法在表間關係部分講)
CHECK
l檢查約束要求取值符合特定的範圍;
l一般用在取值基數少的情況下使用,如狀態、性別等;
l檢查約束上建立位圖索引會是一個很不錯的主意;
l增加檢查約束的語法:
ALTER TABLE table_name ADD CONSTRAINT  constraint_name
 CHECK(column_name and conditaion);
l原則上,檢查約束應該在數據庫設計階段就已經定義好,因此在創建表時就應建立:
XB    CHAR(1) default '男' 
         constraint CKC_XB_STUDENT check (XB is null or ( XB in ('男','女') ))
 
啓用、禁用、刪除和重命名約束
l啓用語法(詳細參考Oracle官方文檔) :
ALTER TABLE table_name ENABLE CONSTRAINT  constraint_name;
l禁用語法(詳細參考Oracle官方文檔) :
    ALTER  TABLE table_name DISABLE CONSTRAINT  constraint_name;
l刪除語法(詳細參考Oracle官方文檔):
    ALTER  TABLE table_name DROP CONSTRAINT  constraint_name;
l修改語法(詳細參考Oracle官方文檔) :
    ALTER  TABLE table_name MODIFY CONSTRAINT  constraint_name;
l重命名
    ALTER  TABLE table_name RENAME CONSTRAINT  old_name TO new_name;
 
重要提醒:強烈建議此類管理功能一律使用工具(如TOAD)來實現。
 
約束使用經驗談
l能定義爲NOT NULL的一律定義爲NOT NULL,如果確實可能取值爲NULL,建議使用默認值後再定義爲NOT NULL(如日期型和數字型),此舉好處很多;
l網絡連接速度慢,客戶端要求響應時間快的,約束最好放在前臺程序實現,反之最好放在後臺實現;
l由於唯一約束實際上是唯一索引,掃描最快,所以能建議唯一約束的一定要使用唯一約束;
l能命名的約束要儘量命名,以便於維護和分析(索引);
lCHCEK約束儘量使用NOT NULL,如檢索較多,建立位圖索引。
 
表間關係
主從表
   如果表A跟表B之間的關係是1:n,則A表和B表之間是主從關係,即A表是主表,B表是從表。主從表經常在主表上使用刪除觸發器來保證A表的記錄被刪除時,B表中對應的記錄通過觸發器自動被刪除,從而維持數據的一致性。
  
 
 
主鍵
語法:
   ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY(column1,column2,…);
   也可以創建表同步創建主鍵
 create table Student  (
   XH                   CHAR(4)                          not null,
   XM                   VARCHAR2(10),
   NL                   INTEGER,
   XB                   CHAR(2)                        default '男' 
         constraint CKC_XB_STUDENT check (XB is null or ( XB in ('男','女') )),
   JG                   VARCHAR2(10),
   constraint PK_STUDENT primary key (XH)
);
外鍵
語法:
   ALTER TABLE table_name1 ADD CONSTRAINT constraint_name FOREIGN KEY(column) REFRENCE table_name2(column);
create table gjdm  (
   GJDM                 CHAR(3)                          not null,
   GJMC                 VARCHAR2(60)                     not null,
   GJJC                 VARCHAR2(20),
   YWMC                 VARCHAR2(32),
   DQDM                 CHAR(8),
   WHR                  VARCHAR2(20),
   WHRQ                 DATE,
   constraint PK_gjdm primary key (GJDM)
);
alter table PTJC_GJDM
   add constraint FK_gjdm_FK_dqdm foreign key (DQDM)
      references dqdm (DQDM);
 
表連接
1.相等連接
  相連接的兩個表或視圖中兩個字段的取值完全相同的連接。
2.自連接
  一個表自己與自己進行的連接。
SELECT e1.last_name||' works for '||e2.last_name
"Employees and Their Managers"
FROM employees e1, employees e2
WHERE e1.manager_id = e2.employee_id AND e1.last_name LIKE 'R%'
ORDER BY e1.last_name;
3.內連接
  內連接又稱爲簡單連接,是僅僅返回滿足條件的行數據的一種連接, 內連接 是相較於外連接的一個概念
 
4.外連接
  外連接不僅返回滿足條件的數據,也返回在一個表中存在而在另外一個表中不存在的數據,是對內連接的一種擴展, 又分爲左外連接和右外連接 第十二 課中左外連接內容如下
 
左外連接是使用Left join、或left outer join或者在右側表使用“(+)”,表示以左表爲驅動表,左表的記錄全部顯示出來,右表匹配的數據才才顯示出來,即左表不加限制,右表加限制。
示例:
 (1). select  * from classes a                   --(15 lines)
 (2). select  * from classes_2 a              --(3 lines)
 --
第十二課中右外連接內容如下
使用right join、或right outer join或者在左側表使用“(+)”,表示以右表爲驅動表,右表的記錄全部顯示出來,左表匹配的數據才才顯示出來,即右表不加限制,左表加限制。示例:
 (1). select *                                           --(3 lines,右表3行,左表匹配3行)
            from classes a,  classes_2 b 
             where a.bjbh(+)  = b.bjbh;
 (2). select * from classes a right  join classes_2 b               --(同(1))
            on a.bjbh  = b.bjbh
 (3). select * from classes a right outer  join classes_2 b      --(同(1))
      on a.bjbh  = b.bjbh
---
 
序列
  序列(SEQUCENCE)其實就是順序號的記數器,按定義的取值方向不斷變化,一般用來給表當主鍵,此時該主鍵往往是代理主鍵。
 
 
語法1:
 CREATE SEQUENCE sequence_name;
 
語法2:
 CREATE SEQUENCE sequence_name
 [INCREMENT BY increment_value]
 [START WITH start_value]
 [MAXVALUE max_value]
 [MINVALUE min_value]
 [CYCLE];
 
 
使用方法:
SELECT sequence_name.nextval
  FROM DUAL;
 
在INSERT語句的VALUE部分可以直接使用sequence_name.nextval取值
 
 
同義詞
   同義詞就是別名,作用是將應用的對象加以簡化。訪問其它用戶已經授權的表,需要用格式:user_name.table_name的格式,因此可以使用同義詞將簡化對錶的訪問。
  語法:
CREATE [PUBLIC] SYNONYM synonym_name FOR object_name
其中[PUBLIC]選項表示是公共同義詞。
  修改同義詞
 原則:先刪除後建立
 語法:
   DROP [PUBLIC] SYNONYM synonym_name ;
 
DBLINK
   數據庫鏈接是用來在一個數據庫中訪問另外一個數據庫中已經授權的對象, 一般用作分佈式數據庫接口
  語法:
CREATE [SHARED][PUBLIC] DATABASE LINK dblink_name
[CONNECT TO [ usrer] [ current_user] IDENTIFIED BY  password] [AUTHENTICATED BY user IDENTIFIED BY password] USING connect_string
 
   使用方法:
 object_name@dblink_name
 
使用
1.序列往往用作代理主鍵,即一個表的主鍵應該是聯合主鍵時,採用序列來建立一個代理作爲主鍵,而聯合主鍵往往定義爲唯一索引;
2.同義詞是用來簡化對其他數據庫中對象、或者同一數據庫中其它模式的對象訪問的,往往與DBLink一起使用;
3.如果前端程序採用Java Hibernate框架,原則上應儘量多的使用同義詞,並在其模型xml文件中指定表的代理主鍵id對應的序列,此舉會大大簡化編程;
4.基於數據庫的不同物理地址的數據庫接口開發,一個非常簡便的方法就是使用dblink+同義詞+存儲過程+oracle Job,並定義和記錄自己的日誌。
 
習題
1.Oracle的優化器分哪兩種類型?其對SQL的執行一般包括哪些方法,結合第21課的內容採用執行計劃舉例說明。
2.繪製Oracle優化器模型結構圖,並簡單加以說明。
3.爲什麼要對錶和索引等數據庫對象進行分析?如何查看自動收集統計信息的任務,並寫出啓用和禁用該任務的PL/SQL塊。
4.如何查看錶或者索引是否被分析過?
5.對錶和索引進行分析後,其數據分別存放在哪些數據字典中 ?各有哪些重要信息,試舉例說明之。
6.不同類型的約束分別建議在什麼情況下時候?
7.如何啓用和禁用約束,什麼情況下對可空約束改成非空約束數據庫會報錯?
8.舉例說明序列和同義詞,並解釋哪些情況下應該儘量使用序列。
 
轉載請註明【http://sishuok.com/forum/blogPost/list/0/6373.html】 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章