詳聊驗(yàn)證Oracle SQL語句
學(xué)習(xí)Oracle時,你可能會遇到驗(yàn)證Oracle SQL語句問題,這里將介紹驗(yàn)證Oracle SQL語句問題的解決方法,在這里拿出來和大家分享一下。檢查共享池中是否有相同的語句存在。假如執(zhí)行的SQL語句已經(jīng)在共享池中存在同樣的副本,那么該SQL語句將會被軟解析,也就是可以重用已解析過的語句的執(zhí)行計(jì)劃和優(yōu)化方案,可以忽略語句解析過程中最耗費(fèi)資源的步驟,這也是我們?yōu)槭裁匆恢睆?qiáng)調(diào)避免硬解析的原因。這個步驟又可以分為兩個步驟:
(1)驗(yàn)證Oracle SQL語句是否完全一致。在這個步驟中,Oracle將會對傳遞進(jìn)來的SQL語句使用HASH函數(shù)運(yùn)算得出HASH值,再與共享池中現(xiàn)有語句的 HASH值進(jìn)行比較看是否一一對應(yīng)?,F(xiàn)有數(shù)據(jù)庫中SQL語句的HASH值我們可以通過訪問v$sql、v$sqlarea、v$sqltext等數(shù)據(jù)字典中的HASH_VALUE列查詢得出。如果SQL語句的HASH值一致,那么ORACLE事實(shí)上還需要對SQL語句的語義進(jìn)行再次檢測,以決定是否一致。那么為什么Oracle需要再次對語句文本進(jìn)行檢測呢?不是SQL語句的HASH值已經(jīng)對應(yīng)上了?事實(shí)上就算是SQL語句的HASH值已經(jīng)對應(yīng)上了,并不能說明這兩條SQL語句就已經(jīng)可以共享了。我們首先參考如下一個例子:假如用戶A有自己的一張表EMP,他要執(zhí)行查詢語句:select * from emp;用戶B也有一張EMP表,同樣要查詢select * from emp;這樣他們兩條語句在文本上是一模一樣的,他們的HASH值也會一樣,但是由于涉及到查詢的相關(guān)表不一樣,他們事實(shí)上是無法共享的。假如這時候用戶 C又要查詢同樣一條語句,他查詢的表為scott下的公有同義詞,還有就是SCOTT也查詢同樣一張自己的表emp,情況會是如何呢?
我們可以看到這四個查詢的語句文本和HASH值都是一樣的,但是由于查詢的對象不同,只有后面兩個語句是可以共享的,不同情況的語句還是需要硬解析的。因此在檢查共享池共同SQL語句的時候,是需要根據(jù)具體情況而定的。
(2)驗(yàn)證Oracle SQL語句執(zhí)行環(huán)境是否相同。比如同樣一條SQL語句,一個查詢會話加了/*+ first_rows */的HINT,另外一個用戶加/*+ all_rows */的HINT,他們就會產(chǎn)生不同的執(zhí)行計(jì)劃,盡管他們是查詢同樣的數(shù)據(jù)。我們下面就一個實(shí)例來說明SQL執(zhí)行環(huán)境對解析的影響,我們通過將會話的 workarea_size_policy變更來查看對同樣一條SQL語句執(zhí)行的影響。
Oracle根據(jù)提交的SQL語句再查詢相應(yīng)的數(shù)據(jù)對象是否有統(tǒng)計(jì)信息。如果有統(tǒng)計(jì)信息的話,那么CBO將會使用這些統(tǒng)計(jì)信息產(chǎn)生所有可能的執(zhí)行計(jì)劃(可能多達(dá)成千上萬個)和相應(yīng)的Cost,最終選擇Cost最低的那個執(zhí)行計(jì)劃。如果查詢的數(shù)據(jù)對象無統(tǒng)計(jì)信息,則按RBO的默認(rèn)規(guī)則選擇相應(yīng)的執(zhí)行計(jì)劃。這個步驟也是解析中最耗費(fèi)資源的,因此我們應(yīng)該極力避免硬解析的產(chǎn)生。至此,解析的步驟已經(jīng)全部完成,Oracle將會根據(jù)解析產(chǎn)生的執(zhí)行計(jì)劃執(zhí)行SQL語句和提取相應(yīng)的數(shù)據(jù)。
【編輯推薦】