關于優化這個體系博大精深,例如内核優化、系統優化、中間件優化、oracle優化、SQL優化、網絡優化等等,網上很多思路都比較偏,比較雜,後面小編會花比較多時間去梳理下這方面内容,深入研究下這方面,試着去做個大緻優化的體系和思路。
下面主要講索引方面的内容,基本概念就不做介紹啦。
1. 若沒有索引,搜索某個記錄時(例如查找name='wish')需要搜索所有的記錄,因為不能保證隻有一個wish,必須全部搜索一遍
2. 若在name上建立索引,oracle會對全表進行一次搜索,将每條記錄的name值哪找升序排列,然後構建索引條目(name和rowid),存儲到索引段中,查詢name為wish時即可直接查找對應地方
3.創建了索引并不一定就會使用,oracle自動統計表的信息後,決定是否使用索引,表中數據很少時使用全表掃描速度已經很快,沒有必要使用索引
1、索引類型
從總的概念上來說,索引分為B樹索引(也叫平衡樹索引,即就是什麼都不寫,最常用)和位圖索引(多用于數據倉庫)。這兩種索引在邏輯結構(存儲)上完全不同。
(1)唯一索引:
唯一索引确保在定義索引的列中沒有重複值,Oracle 自動在表的主鍵列上創建唯一索引。
使用CREATE UNIQUE INDEX語句創建唯一索引
語法:create unique index index_name on table_name (column_name);
具體列值: 索引相關列上的值必須唯一,但可以不限制NULL值。
(2)組合索引:
組合索引是在表的多個列上創建的索引,索引中列的順序是任意的。
如果 SQL 語句的 WHERE 子句中引用了組合索引的所有列或大多數列,則可以提高檢索速度
語法:create index index_name on table_name (column_name1,column_name2);
具體列值:該表中的元組由兩列共同确定一行,例如班級号 學号 唯一确定一個學生。
(3)反向鍵索引:
反向鍵索引反轉索引列鍵值的每個字節,為了實現索引的均勻分配,避免b樹不平衡。
通常建立在值是連續增長的列上,使數據均勻地分布在整個索引上
創建索引時使用REVERSE關鍵字
語法:create index index_name on table_name (column_name) reverse;
具體列值: 适用于某列值前面相同,後幾位不同的情況,例如
sno: 1001 1002 1003 1004 1005 1006 1007
索引轉化:1001 2001 3001 4001 5001 6001 7001
(4)位圖索引:
位圖索引适合創建在低基數列上
位圖索引不直接存儲ROWID,而是存儲字節位到ROWID的映射
節省空間占用
如果索引列被經常更新的話,不适合建立位圖索引
總體來說,位圖索引适合于數據倉庫中,不适合OLTP中
語法:create bitmap index index_name on table_name (column_name);
具體列值: 不适用于經常更新的列,适用于條目多但取值類别少的列,例如性别列。
(5)基于函數的索引:
基于一個或多個列上的函數或表達式創建的索引,表達式中不能出現聚合函數
不能在LOB類型的列上創建
創建時必須具有 QUERY REWRITE 權限
語法:create index index_name on table_name (函數(column_name));
具體列值: 不能在LOB類型的列上創建,用戶在該列上對該函數有經常性的要求。
例如:用戶不知道存儲時候姓名是大寫還是小寫,使用
select * from student where upper(sname)=’TOM’;
2、索引結構
索引的結構是一個倒立的樹狀結構,其中每個節點的左子樹比他的右子樹小,索引最終指向表裡面的數據與表裡面的數據對應。
如上圖,前三行是索引的内部構造,第三行與最後一行,這是索引指向表裡數據的一個指向。索引是建立在列上的。最後一行是索引建立在表中某列上的值。
根節點塊 :如果索引列的值>0時,指向B1這個分支節點塊,如果索引列的值>500時,指向B2這個分支節點塊,如果索引列的值>1000時,指向B3這個分支節點塊。
分支節點塊:對于B1來說,再進行細分 如果索引列的值>0且<200時,指向L1這個分支節點塊,如果索引列的值>200且<400時,指向L2這個分支節點塊,如果索引列的值>400且<500時,指向L3這個分支節點塊。
葉子節點塊: 對于L1來說,如果數據行的值為0,那就放在R1這個數據行中,如果數據行的值為29,那就放在R2這個數據行中,如果數據行的值為190,那就放在R3這個數據行中,等。
當字段上建有索引時,通常以下情況會使用索引:
INDEX_COLUMN = ?
INDEX_COLUMN > ?
INDEX_COLUMN >= ?
INDEX_COLUMN < ?
INDEX_COLUMN <= ?
INDEX_COLUMN between ? and ?
INDEX_COLUMN in (?,?,...,?)
INDEX_COLUMN like ?||'%'(後導模糊查詢)
T1. INDEX_COLUMN=T2. COLUMN1(兩個表通過索引字段關聯)
一般在什麼字段上建索引?
主鍵及外鍵通常都要有索引,其它需要建索引的字段應滿足以下條件:
1、字段出現在查詢條件中,并且查詢條件可以使用索引;
2、語句執行頻率高,一天會有幾千次以上;
以下是一些字段是否需要建B-TREE索引的經驗分類:
索引對DML(INSERT,UPDATE,DELETE)附加的開銷有多少?
這裡還沒有去做實驗認真測試過,主要與每個表記錄的大小及索引字段大小密切相關,參考了其他人對一個普通表的測試數據:
索引對于Insert性能降低56%
索引對于Update性能降低47%
索引對于Delete性能降低29%
因此對于寫IO壓力比較大的系統,表的索引需要仔細評估必要性,另外索引也會占用一定的存儲空間。如果不涉及增删改,可以考慮使用索引。
PS:順便問一個問題:B 樹跟B樹索引有什麼區别?
關于索引這塊講的還是比較淺顯,後面再介紹相關的實驗加深下對于索引這一塊的印象,感興趣的朋友可以關注下!
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!