1、基本原理
Oracle的日志:Oracle中為了提高硬盤寫的效率,采用內存中數據緩沖區來保存數據,等到一定量或一定時間後才寫到磁盤(DBWR)。
這個時候假如斷電之類的故障發生,數據緩沖區的數據將丟失。
所以需要日志來保存記錄,它也有個緩沖區,每隔3秒或Commit或滿3分之1 都會觸發LGWR進程寫到REDO文件中(日志文件)。
回滾:Oracle中采用多版本控制來進行並發。當寫數據時,先把原數據寫入UNDO中(回滾表空間)。然後再將原數據的位置修改為新數據。(其它進程讀的時候,讀回滾表中的數據,這就防止了髒讀)。如果Commit了,那就回收回滾表空間。如果回滾了,那就將前鏡像讀出來覆蓋原位置。
關於回滾的數據的所有操作,都要涉及日志,所以有UNDO就會有大量REDO!
DML的REDO:假如插入的日志為6(省略單位)(UNDO記錄插入記錄的rowid)。更新的日志就是7(UNDO記錄更新記錄的那列的舊字段)。而刪除的日志就是32(UNDO記錄原整行數據)。
2、批量插入
綁定變量:減少SQL的解析。
批量提交:減少與Oracle的交互。減少IO。
3、存儲機制
SEGMENT -> 表示一張表。包含多個Extent。 EXTENT -> 表示擴展的最小單位。當數據增多時,按照一個EXTENT來進行擴充的。包含8個塊。 Block -> 表示一個塊,存儲的最小單位(8KB)。頭,表目錄,行目錄,可用空間(空余空間),數據區。
4、臨時表與分區與聚簇
臨時表優點:1.高效的刪除記錄,基於事務的全局臨時表COMMIT或SESSION連接退出後,臨時表記錄自動刪除(產生的記錄也要少的多)。 2.針對不同會話數據獨立,不同SESSION訪問看到的結果不同。分區:數據的完全獨立分離(不同與索引的產生地址)。所以它會產生多個SEGMENT(就是多張表)。 1.當根據分區字段查詢時,可以高效的分區消除。只訪問一部分。 2.強大的分區操作,truncate刪除,數據轉移,分區切割,分區合並。 3.全局索引,只有分區列才能創建全局索引(或前綴)。很多分區操作會使全局索引失效,必須重建。 4.局部索引,其它字段就只能構建局部索引。當進行查詢時,需要訪問所有分區的局部索引,有時候,反而效率更低(每個索引基本需要4次IO)。聚簇表:只能使用主鍵索引來約束數據的存放位置(通過organization index)。(默認主鍵是非聚簇)。優點是查詢所有時不需要有回表的操作。缺點是更新開銷更大。
5、索引
B+樹的存儲方式。50W條的時候高度為3。這時需要4次IO(包括回表)。索引的優點: 1.COUNT、SUM、AVG。但是注意當有空值時(B樹不儲存空值),也許開銷更大。 2.MAX、MIN。但是注意不能同時使用MAX+MIN。因為這個時候Oracle為了原子性。會全表掃描。 3.ORDER BY(排序消耗大)、DISTINCT(會排序後消除)、UNION(注意單獨的UNION是需要排序去重的)。 4.組合索引:避免回表。但是注意查詢范圍時,必須按照組合的前綴順序來查(等值無所謂)。有等值有范圍時,等值在前,范圍在後。 5.位圖索引:大量重復,極少更新時建立。
6、表連接
1.嵌套連接:用的最多,讀出驅動表的所有適合行,然後一個一個拿到被驅動表中去根據連接條件查詢(所以為了減少IO,驅動表最好為小的)。所以需要驅動表限制條件有索引,被驅動表連接條件有索引。 2.哈希連接:讀出驅動表建立hash(驅動表小),讀出被驅動表來查找hash。不支持大於小於的比較。 3.排序合並:讀出兩個表的元素,分別排序,然後歸並。兩個表的連接條件都要有索引。不支持不等於。
參考:收獲,不止Oracle。