Oracle——常用優化原則

一、什麼是索引

百度百科: 在oracle索引是一種供服務器在表中快速查找一個行的數據庫結構。合理使用索引能夠大大提高數據庫的運行效率。

個人解讀:
1、索引是與表相關的一個可選結構,表中可以存在索引,也可以不存在索引。
2、在邏輯上和物理上都獨立於表,索引和表可以存放在不同的表空間下面(邏輯上分離),可以存放在不同的磁盤下面(物理上分離)。
3、索引用於快速查找表的內容,可以提高SQL性能。

二、索引的類型

B-Tree索引(平衡樹索引)

B-Tree索引適合於數據重複低的字段,常用於主鍵 唯一約束

Bitmap索引(位圖索引)

適用於列的基數很少、數據重複多、更新少的

text索引(全文索引)

當字段裏存儲的都是文本時適合用全文索引,常用於搜索文字

三、索引的創建

1、唯一索引:鍵值不重複

CREATE UNIQUE INDEX index_name ON table_name (column_name)

2、一般索引:鍵值可重複

CREATE INDEX index_name ON table_name (column_name)

3、複合索引:綁定了多個列

CREATE INDEX index_name ON table_name (column_name1,column_name2)

四、數據庫優化

1、SQL使用索引的例子

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(兩個表通過索引字段關聯)

2、SQL不使用索引的例子

//不等於操作不能使用索引
INDEX_COLUMN <> ?
INDEX_COLUMN not in (?,?,...,?)

//經過普通運算或函數運算後的索引字段不能使用索引
function(INDEX_COLUMN) = ?
INDEX_COLUMN + 1 = ?
INDEX_COLUMN || 'a' = ?

//含前導模糊查詢的Like語法不能使用索引
INDEX_COLUMN like '%'||?
INDEX_COLUMN like '%'||?||'%'

//B-TREE索引裏不保存字段爲NULL值記錄,因此IS NULL不能使用索引
INDEX_COLUMN is null

//Oracle在做數值比較時需要將兩邊的數據轉換成同一種數據類型,如果兩邊數據類型不同時會對字段值隱式轉換,相當於加了一層函數處理,所以不能使用索引。
NUMBER_INDEX_COLUMN='12345'
CHAR_INDEX_COLUMN=12345
a.INDEX_COLUMN=a.COLUMN_1

3、常用優化方法

注意where字句中的連接順序
ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.
尤其是“主鍵ID=?”這樣的條件。

SELECT子句中避免使用 ‘ * ‘
ORCLE在解釋的過程中,會將*依次轉換爲所有的列名,這個工作是通過查詢數據字典來完成的, 這意味着將耗費更多的時間。

避免在索引列上使用NOT
我們要避免在索引列上使用NOT, NOT會產生在和在索引列上使用函數相同的影響. 當ORACLE”遇到”NOT,他就會停止使用索引轉而執行全表掃描。

避免在索引列上使用計算
WHERE子句中,如果索引列是函數的一部分.優化器將不使用索引而使用全表掃描。

避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以爲空的列,ORACLE性能上將無法使用該索引。對於單列索引,如果列包含空值,索引中將不存在此記錄。對於複合索引,如果每個列都爲空,索引中同樣不存在此記錄。

注意通配符%的影響
含前導模糊查詢的Like語法不能使用索引,如:
INDEX_COLUMN like ‘%’||?
後導模糊查詢的Like語法可以使用索引,如:
INDEX_COLUMN like ?||’%’

避免改變索引列的類型
Oracle在做數值比較時需要將兩邊的數據轉換成同一種數據類型,如果兩邊數據類型不同時會對字段值隱式轉換,相當於加了一層函數處理,導致不能使用索引。

用(UNION)UNION ALL替換OR (適用於索引列)
通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果。對索引列使用OR將造成全表掃描。注意,以上規則只針對多個索引列有效。如果有column沒有被索引,查詢效率可能會因爲你沒有選擇OR而降低。

用UNION-ALL 替換UNION ( 如果有可能的話)
當 SQL語句需要UNION兩個查詢結果集合時,這兩個結果集合會以UNION-ALL的方式被合併, 然後在輸出最終結果前進行排序。 如果用UNION ALL替代UNION, 這樣排序就不是必要了, 效率就會因此得到提高。 需要注意的是,UNION ALL 將重複輸出兩個結果集合中相同記錄。

Exists替換DISTINCT
帶有DISTINCT,UNION,MINUS,INTERSECT的SQL語句會啓動SQL引擎 執行耗費資源的排序(SORT)功能。DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序。 通常, 帶有UNION,MINUS ,INTERSECT的SQL語句都可以用其他方式重寫。

合理的使用Exists和In
EXISTS:首先檢查主查詢,然後運行子查詢直到它找到第一個匹配項,這就節省了時間。
IN子查詢時:首先系統先將主查詢掛起,然後執行子查詢,並將獲得的結果列表存放在一個加了索引的臨時表中。待子查詢執行完畢,再執行主查詢。這也就是使用EXISTS比使用IN通常查詢速度快的原因。

1) select * from T1 where exists(select t1.id from T2 where T1.id=T2.id) ;
2) select * from T1 where T1.id in (select T2.id from T2) ;

T1數據量小而T2數據量非常大時,T1<<T2 時,1) 的查詢效率高。
T1數據量非常大而T2數據量小時,T1>>T2 時,2) 的查詢效率高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章