ORACLE SQL查詢優化

1、優化解析時間

語句緩存  SQL語句 -》共享池 -》高速緩存

軟解析:從共享池中 取出 以前的解析 過的語句
硬解析:重新開始新的解析

硬解析會消耗資源多很多,SQL可以複用還是要複用的。

sql語句 -> hsah 值 當做key ,<key,sql>存入高速緩存中(Sql語句的大小寫會影響KEY)
使用綁定變量,sql還可以複用

所以,sql查詢兩次的大小寫不要變來變去,還有,使用綁定變量。

select * from v$sql 可以查詢出在高速緩存池的sql語句

2、索引查詢

在必要列中添加索引。

索引分爲 唯一性索引、普通索引、組合索引。

組合索引:
1:適用在單獨查詢返回記錄很多,組合查詢後忽然返回記錄很少的情況:如以類別和
2:要考慮順序,第一列爲引導列,
oracle索引掃描類型:索引範圍掃描、索引唯一掃描、索引全掃描、索引跳躍掃描、索引快速全掃描
索引唯一掃描: 對 unique、primary key索引作爲調節的時候,會使用唯一掃描
索引範圍掃描:
    返回值不唯一,索引列可以是唯一索引,也可以是不唯一索引,條件可以是 <、>、=等
    範圍掃描索引表
索引全掃描:
    1:選擇列是唯一性索引,也就是全掃描索引就可以得到值 (id 爲索引列)
        比如 select id from tb_xxx
    2:使用max(索引列)
    select max(dabh) from tb_da
索引跳躍掃描
    複合索引中,非引導列查詢可能走索引跳躍掃描
索引快速全掃描
    當索引列有非空約束時,這時索引

怎麼查詢是怎麼走索引的呢,對了,執行計劃:

方法1:
EXPLAIN PLAN FOR
SELECT * FROM SCOTT.EMP; --要解析的SQL腳本
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

(PL/SQL F5 也能進入此處的執行計劃)

不用執行SQL語句就可以進行分析,但信息量少

方法2:sqlplus命令
set autotrace traceonly explain;
select * from ....

通過執行計劃,就可以看到到底是全表查詢還是索引查詢。

你還可以通過執行計劃看到TABLE ACCESS BY INDEX ROWID 操作,這個就是回表,回表也有一定的時間消耗

回表:
TABLE ACCESS BY INDEX ROWID
oracle查詢的列 不在索引列時,會根據rowid去回表查詢

不走索引的情況(SQL優化的重點):
1:name like '%ss%' 會不走索引
2:查詢是 索引 列值 ='' 或者 is null,null值不會存在B樹裏面,所以不會走索引
3:not in 不會走索引,!= 不會走索引
4:當查詢的數量值特別多(佔有 20% 以上?),直接走全表查詢,不走索引。
    像 <、> 要根據返回值的數量來決定走不走索引,oracle 會智能統計信息,來優化執行計劃。
5:在包含有null值的table列上建立索引,當時使用select count(*) from table時不會使用索引

 

3、in、or的優化

網上很多說 in 不走索引,其實是錯誤的,那應該是老版本的數據庫,in走不走索引,應該還要看返回列的數量多少,通常in是走索引的。

通常情況下in的效率會比or高

in的優化:
思路1:
sql語句中經常使用in來查詢
oracle有個限制,不能超過1000個參數
而且這種用法很低效,可以把參數設爲一個表,做hash join查詢提高性能

1、用exists來代替(特定情況下)
2:用left join 代替

 

In和exists對比:
若子查詢結果集比較小,優先使用in,若外層查詢比子查詢小,優先使用exists。
因爲若用in,則oracle會優先查詢子查詢,然後匹配外層查詢,
若使用exists,則oracle會優先查詢外層表,然後再與內層表匹配。最優化
匹配原則,拿最小記錄匹配大記錄。

 

union all : 兩張表進行合併,不去重,不排序,效率比union高很多
union: 兩張表進行合併,去重+排序
select id,dabh from tb_a where xxx
union all
select id,dabh from tb_b,where xxx
在不用索引的情況下,用union all代替in的效率會高,具體還需要測試

 

 

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