Oracle 執(zhí)行計劃(explain plan for)

一、什么是執(zhí)行計劃

所謂執(zhí)行計劃,就是在執(zhí)行一個 SQL 前,做出的一份數(shù)據(jù)庫認為最佳的方案。好比在北京上班,是坐地鐵去還是公交車亦或開車自駕等等。如果坐地鐵,需要從哪兒換成之類的,... ...從各種方案中選擇一個自認為最佳的方案。這個方案在數(shù)據(jù)庫里面即為執(zhí)行計劃。也認為最合適的方案。

二、解析的概念

解析就是為 sql 生成執(zhí)行計劃的過程。解析分為軟解析和硬解析。

三、統(tǒng)計信息與動態(tài)采樣

統(tǒng)計信息的作用就是為解析 sql 提供的數(shù)據(jù)支持,也就是為了更好的選擇執(zhí)行計劃。簡單說就是統(tǒng)計信息反映表中數(shù)據(jù)分布的情況。

如果統(tǒng)計信息沒有收集,數(shù)據(jù)庫在解析 sql 的過程中會根據(jù)一定的比例去表中采樣,采樣的結(jié)果作為 sql 執(zhí)行路徑所需代價的依據(jù)。這就是動態(tài)采樣。

四、NULL 這個特殊的東西

NULL 是個特殊的一個存在。

從定義上來講,NULL 就是一個不確定的數(shù)據(jù)。所以無論對 NULL 做任何操作,結(jié)果還是 NULL。

另外,對于 Oracle 數(shù)據(jù)庫來說,索引里面沒有 null,索引里面沒有 NULL 會有什么影響呢?哈哈,見“索引快速全掃描”部分。

五、索引相關(guān)執(zhí)行計劃(補充索引選擇性的概念)

1 全表掃描(full table scan)

  1. 測試數(shù)據(jù)

create table t1 as select * from dba_objects;

2)看執(zhí)行計劃

explain plan for select * from t1 where t1.object_id=19791;

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

3)注意動態(tài)采樣與filter

2 索引唯一掃描(index unique scan)

1)創(chuàng)建唯一性索引

create unique index t1_objectid on t1(object_id);

2)收集統(tǒng)計信息

exec dbms_stats.gather_table_stats('ZQ','T1',cascade=>true);

  1. 查看執(zhí)行計劃

explain plan for select * from t1 where t1.object_id=19791;

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

4)注意動態(tài)采樣的消失與access

3 索引范圍掃描(index range scan)

1)測試數(shù)據(jù)

create table t2 as select * from dba_objects;

  1. 創(chuàng)建非唯一性索引

create index t2_objectid on t2(object_id);

  1. 收集統(tǒng)計信息

exec dbms_stats.gather_table_stats('ZQ','T2',cascade=>true);

4)查看執(zhí)行計劃

explain plan for select * from t2 where t2.object_id=19791;

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

5)查看執(zhí)行計劃

explain plan for select * from t1 where t1.object_id>131790;

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

4 索引快速全掃描(index fast full scan)

  1. 查看執(zhí)行計劃

explain plan for select /+index(t2 t2_objectid)/object_id from t2 order by object_id;

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

        --走全表掃描

            insert into t2 select * from t2;

            commit;

insert into t2 select * from t2;

            commit;

     2) 收集統(tǒng)計信息,然后看執(zhí)行計劃

exec dbms_stats.gather_table_stats('ZQ','T1',cascade=>true);

explain plan for select object_id from t2 order by object_id;

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

        --走全表掃描

3) 創(chuàng)建組合索引,并收集統(tǒng)計信息

create index t2_id_name on t2(object_id,object_name);

exec dbms_stats.gather_table_stats('ZQ','T2',cascade=>true);

explain plan for select object_id,object_name from t2;

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

--走全表掃描

explain plan for select /+index(t2,t2_id_name)/object_id,object_name from t2;

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

---------------------為啥,哈哈哈哈哈哈,not null

  1. object_id字段設(shè)置成not Null,走索引快速掃描

alter table t2 modify object_id not null;

explain plan for select /+index(t2,t2_id_name)/object_id,object_name from t2;

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

  1. 使用count,索引全掃描

explain plan for select count(object_id) from t2 ;

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

5 索引全掃描(index full scan)

1)查看執(zhí)行計劃

explain plan for select t1.object_id from t1 order by t1.object_id;

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

--注意索引快速全掃描無序,索引全掃描有序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容