SQL優化總結1

2021-07-06 09:44:02 字數 4142 閱讀 1490

oracle 優化手段:

指執行sql時繫結變數,減少軟解析時間。

result cache 將某更新不頻繁的表的結果中存在快取中,下次直接讀快取,如果改表有更新,快取自動失效

表聯合查詢時,9i前大表(結果集),小表(結果集)的位置

block塊的大小的設定,設定小,則io頻繁,cup低耗,反之反之

索引:主外來鍵索引,分割槽表中有全域性索引和區域性索引,位圖索引

分割槽表:有大表時,通過分割槽條件在小範圍內查詢

臨時表:在事物或session結束後,系統自動清理資料

直接路徑插入,不進行redo,即不經過logbuffer插入很快,但第一次讀即物理讀,所以第一次讀慢

高不位線

keep

count(字段) 不統計該了段為null的記錄

count 列名或常數,與*效能完全一樣。count(列)列越靠前,越快

表中的列,越靠前,訪問越快

聚合因子,將有序的列作索引,否則索引無序,索引的位置很離散(索引回表的資料聚合度就低,找得慢)

聯合索引,兩個條件分別能查出很多,但交集少,就建立聯合索引

聯合索引兩個列中,如果乙個列加了等值條件。等值條件放前面

max min 分開成兩個sql查詢,能走索引,放在一條sql不能走索引

因為max,min在一條sql,不能同時看左邊和右

id>=20 and id<=21 

id in (20,21) 後者效率高,因為oracle還會匹配20到21之前的小數

優化器以為前者這個區間內資料據多,所以不走索引

在執行計畫上看:

unique索引:index unique scan 唯一性掃瞄,掃到後就停住

普通索引: index range scan 掃到後還要判斷下乙個符不符合,會多掃一次

unique索引稍稍能提公升一點點

table access by user rowid

rowid是最快的方式,效能之王

優化辦法,把常用的行的rowid存在乙個變數中,下次直接使用

index full scan 全表掃瞄,一次讀取乙個塊

select * from t order by id;

index fast full scan 快速全表掃瞄,一次讀取多個塊

select count(*) from t;

所以快速全掃瞄更快,因為其一次讀取多個塊,不能保證有序

大多情況下,

聚合函式都是快速掃瞄

index full scan (min/max) 前面已經提到,直接在索引表的開始的末端取數,很快

建索引的負面影響:

反向索引 減少熱塊競爭,索引離散儲存,where 範圍查詢無法走索引

預設情況下,建索引會引起全表鎖

但是online建索引時,索引建立的動作會自動等更新結束後進行,更新不會受到阻塞

建立索引會發生全表排序,

排序是乙個很消耗效能的動作,典型地基於吞吐量的動作

索引字段,最好按什麼型別存什麼資料,否則發生資料型別轉換,即查詢時條件欄位或呼叫型別轉換函式,導致索引失效

對索引列進行運算,會引起索引邏輯失效,引起全表掃瞄

索引物理失效的原因:

long修改為clog時,會導致其他列的索引失效

對錶進行move操作導致索引失效

(對大表delete大量資料後,查詢依然很慢,是高水平位沒釋放,所以經常有人通過alter table move的方式來降低高水位,這時卻導致索引物理失效)需要rebuil索引

對於分割槽表,

truncate分割槽   會導致全域性索引物理失效、  不會導致區域性索引失效  增加update global indexes,則全域性索引不會失效

drop分割槽       會導致全域性索引物理失效、  這時已經刪除了,就沒了分割槽索引了 增加update global indexes,則全域性索引不會失效

split分割槽      會導致全域性索引物理失效、  會導致區域性索引失效   增加update global indexes,則全域性索引不會失效

add分割槽        不會導致全域性索引物理失效、不會導致區域性索引失效

exchange       會導致全域性索引失效,       不會導致區域性索引失效  增加update global indexes,則全域性索引不會失效

這幾個操作,對於全域性索引,只要用到update global indexes都不會失效

設定索引並行屬性導致px coordinator

不要在迴圈內commit

like % 會不會走過引不確定,也可能是區域性掃瞄

move外來鍵所在的列,導致外來鍵的表的索引失效,導致 主外來鍵列更新阻塞

反向索引,避免熱塊,但是範圍查詢時,走不了索引

drop表後,閃回操作

flashback table t to before drop

這時索引其實都丟了,得重新建索引,約束也要重建

函式索引

reverse(列)結合 like '%ljb' 使like走部分索引

(col1 desc,col2 asc) 這樣的索引可以避免 sort操作

虛擬索引,用來先測試看執行計畫會不會用索引,如果不會用,就不建這個索引

因為當資料量大的時候,建立索引代價大,在不確定索引是否起效時,不要隨意建,所以用虛擬索引先實驗一下

位圖索引,把某個表的所有行的某個列(該的取值範圍很小,比如說只有0和1)的值相加,就是這個表的總行,所以count操作會很快

位圖索引應用場合,重複度很高的列,並且很少改動的列

函式索引,就是把某個列通過函式計算的結果存索引表中

全文檢索索引:基於oracle的lexer全文檢索演算法

基於語義查詢'高興',『高』都能快速查詢

但『興』查不到結果,這是乙個陷阱,因為它基於語義分析的演算法

其次,在更新操作時,還要執行同步命令才能更新成功

同步語法:exec ctx_dd1.syncindex('列名','列值');

對於判斷乙個表是不是空的需求的優化,select * from t where rownum=1判斷這個結果是不是空

特殊的函式索引

create index id_status on  (case when status='n' then 'n' end);

總記錄很多,但記錄裡id_status為n的情況很少

當查詢為n的記錄,會走索引

函式索引,函式內容變了,索引一定發重建,否則查詢結果要能是錯的

表的連線方式

如果返回結果資料量很大用hash join 或 merge sort join

反之用nested loop join

hash join 不支援不等值條件

只要是不等值條件就一定走nested join

starts即表訪問次數如果很多,還是neste loop join 則需要注意執行計畫是否真實

蒐集統計資訊,用於優化器生成最優的執行計畫

設定statistics_level=all

oracle優化器會蒐集表的訪問次數,即starts

統計資訊蒐集表

last_analyzed表是上次蒐集的時間

第一次查詢sql後, 會出現

dynamic sampling used for this statement (level=2)

動態取樣被執行

取消動態取樣的sql

select /*+ dynamtic_sampling(t 0)*/ * from t where ..

建索引後,也會自動蒐集統計資訊

獲取執行計畫的6種方式

select * from table(dbms_xplan.display());

statistics_level=all

(預估,不准)explain plan for + 你的sql

(真實)set autotrace on

通過sql_id獲得執行

v$sql檢視中獲取sql_id

select * from t(dbms_xplan.display cursor('sql_id'));

繫結變數會使orafle生成不准的執行計畫

where t.id< var :990

where t.id< var : 9

第一次sql執行後,優化器就會一直走全表掃瞄,因為它以為一直是返回大資料量的結果

實事上第二次只返回少量資料,應該走索引

SQL優化總結

1.首先在建表的時候,選用最合適的字段型別。例如在定義name欄位時,可以使用varchar 32 不要使用char 32 以減少不必要的空間 而在定義郵編 郵編固定6位 時也沒必要使用varchar 6 了,直接使用char 6 會更好 對於性別,省份等可以定義為enum型別,因為數值型的資料檢索...

SQL優化總結

1,子查詢優化後問題 有些欄位的區分度飄忽飄忽不定,比如status欄位。我們這個欄位在專案中使用了索引。老版本優化時把主鍵id查出來放到子查詢中,再用status進行篩選,這樣有效果。公升級了mysql之後,出現慢查詢。這個時候子查詢不再適用,應使用ignore index status idx ...

SQL效能優化1

一 問題的提出 在應用系統開發初期,由於開發資料庫資料比較少,對於查詢sql語句,複雜檢視的的編寫等體會不出sql語句各種寫法的效能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中資料的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中乙個很重要的方面就是sql語句的優化。...