資源描述:
《oracle 11g之前的綁定變量窺視》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、11g之前的綁定變量窺視我們都知道,為了能夠讓SQL語句共享執(zhí)行計(jì)劃,oracle始終都是強(qiáng)調(diào)在進(jìn)行應(yīng)用系統(tǒng)的設(shè)計(jì)時(shí),必須使用綁定變量,也就是用一個(gè)變量來代替原來出現(xiàn)在SQL語句里的字面值。比如,對于下面三條SQL語句來說:selectcol1fromtwherecol2=1;selectcol1fromtwherecol2=2;selectcol1fromtwherecol2=3;我們可以看到,這三條SQL語句幾乎一樣,只有最后where條件里的字面值(分別是1、2、3)不同而已。但是如果寫成這個(gè)樣子,則oracle是不知道這三條S
2、QL語句是一樣的,仍然把它們當(dāng)作三條完全不同的SQL語句,從而在sharedpool里進(jìn)行硬解析,并生成最終的執(zhí)行計(jì)劃。但是我們會(huì)發(fā)現(xiàn),這三個(gè)執(zhí)行計(jì)劃可能都是一樣的,因此后面兩次生成執(zhí)行計(jì)劃的工作可能是完全不必要的,這在典型的OLTP環(huán)境中更是如此。由于解析本身屬于CPU密集型操作,因此為了降低對CPU的消耗,oracle建議將這樣的SQL寫成:selectcol1fromtwherecol2=:v1;然后,分別將1、2、3傳遞給v1,這樣的話,只需要第一次傳入1時(shí)進(jìn)行解析即可。而后面執(zhí)行2、3時(shí),由于SQL文本本身沒有變化,因此直接
3、把執(zhí)行計(jì)劃拿來使用即可,不需要再次生成執(zhí)行計(jì)劃。但是,生成執(zhí)行計(jì)劃本身是基于概率的理論,在不具體表里的數(shù)據(jù)的前提下,根據(jù)你的where條件,來猜測返回的記錄數(shù)大概是多少,從而判斷應(yīng)該采用怎樣的路徑。很明顯,這是一定要參照具體的where條件里的值才能進(jìn)行猜測的。這樣就與節(jié)省CPU的初衷產(chǎn)生了矛盾,因?yàn)楣?jié)省CPU的關(guān)鍵是使用綁定變量,你一旦使用了綁定變量,則oracle豈不是不知道你具體的字面值了嗎?為了解決這一問題,oracle引入了綁定變量窺視。所謂綁定變量窺視,就是指oracle在第一次解析SQL語句的時(shí)候(也就是說該SQL第一次
4、傳入sharedpool),會(huì)將你輸入的綁定變量的值帶入SQL語句里,從而參考你的字面值來猜測該SQL大概會(huì)返回多少條記錄,從而得到優(yōu)化的執(zhí)行計(jì)劃。然后,以后再次執(zhí)行相同的SQL語句時(shí),不再考慮你所輸入的綁定變量的值,直接取出第一次生成的綁定變量。但是,很可惜的是,使用綁定變量從而共享游標(biāo)與SQL優(yōu)化是兩個(gè)矛盾的目標(biāo)。Oracle使用綁定變量的前提,是oracle認(rèn)為大部分的列的數(shù)據(jù)都是分布比較均勻的。從而,使用第一次的綁定變量的值所得到的執(zhí)行計(jì)劃,大多數(shù)情況下都能適用于該綁定變量的其他的值。很明顯,如果第一次傳入的綁定變量的值恰好占
5、整個(gè)數(shù)據(jù)量的百分比較高,從而導(dǎo)致全表掃描的執(zhí)行計(jì)劃。而后來傳入的綁定變量的值都占整個(gè)數(shù)據(jù)量的百分比都很低,則應(yīng)該走索引掃描會(huì)更好的,但是由于使用了綁定變量,從而oracle并不會(huì)再去看你的綁定變量的值,而是直接拿全表掃描的執(zhí)行計(jì)劃來用。這時(shí),由于使用了綁定變量,雖然我們達(dá)到了游標(biāo)共享,從而節(jié)省CPU的目的,但是SQL的執(zhí)行計(jì)劃卻不夠優(yōu)化了。那么我們?nèi)绾卧诮壎ㄗ兞亢蚐QL優(yōu)化之間進(jìn)行取舍呢?在OLTP應(yīng)用中,由于并發(fā)性較高,CPU上的爭用會(huì)比較嚴(yán)重,同時(shí)SQL本身執(zhí)行時(shí)間較短,涉及到的數(shù)據(jù)量較少,解析所占的時(shí)間在整個(gè)SQL執(zhí)行時(shí)間中占的
6、比例較高,而花在I/O上的時(shí)間占的比例較低。因此盡管綁定變量會(huì)有SQL不夠優(yōu)化的問題,還是建議使用綁定變量。但是在DSS應(yīng)用和數(shù)據(jù)倉庫應(yīng)用中,由于并發(fā)性較低,CPU上的爭用較輕,同時(shí)SQL語句的執(zhí)行時(shí)間都很長,而且主要時(shí)間花在等待I/O上,而解析占的比重較低,這時(shí)優(yōu)化SQL執(zhí)行計(jì)劃的重要性就體現(xiàn)出來了。因此,建議不要使用綁定變量,而直接使用字面值。但是大多數(shù)的情況都是混合應(yīng)用,既有OLTP又有數(shù)據(jù)倉庫,這時(shí)就很難完美的解決該問題了。我們先來看一下11g之前的綁定變量窺視是如何工作的,以10g為例。我們先創(chuàng)建一個(gè)表,使得其含有的數(shù)據(jù)分布
7、不均勻,并在該表上創(chuàng)建一個(gè)索引。hr@ora10g>createtablet1asselectobject_idasid,object_namefromdba_objects;hr@ora10g>updatet1setid=1whererownum<=10000;hr@ora10g>commit;hr@ora10g>createindexidx_t1ont1(id);這樣,該表里id為的1記錄有一萬條,而id為其他值的記錄都只有一條。從而,我們構(gòu)建出一個(gè)分布不均勻的測試用表。然后,我們收集一下統(tǒng)計(jì)信息。注意,這里要收集直方圖,為的是要
8、讓CBO知道id列上的數(shù)據(jù)分布不均勻。hr@ora10g>begin2dbms_stats.gather_table_stats(3user,4‘t1‘,5cascade=>true,6method_opt=>‘forc