IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類|軟件專題|手機(jī)版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當(dāng)前所在位置: 首頁數(shù)據(jù)庫Oracle → 教你如何優(yōu)化SQL語句中的物理查詢

教你如何優(yōu)化SQL語句中的物理查詢

時(shí)間:2015-06-28 00:00:00 來源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(0)

  有幾位朋友有這樣的疑問:

  select *

  from tab1, tab2

  where tab1.id = tab2.id and tab1.col1 = 123 and tab2.col1 = 'abc'

  照你所述的執(zhí)行順序,先要tab1和tab2進(jìn)行笛卡爾乘積,再按照tab1.col1 = 123 and tab2.col1 = 'abc'進(jìn)行篩選。這樣的話,效率豈不是很低,數(shù)據(jù)庫有這么愚蠢嗎?

  我想很多人都會(huì)有這個(gè)疑問,包括我在最初學(xué)習(xí)的時(shí)候也提出過這樣的問題。那么,我的這篇文章就結(jié)合這個(gè)問題來討論一下SQL Server的物理查詢處理。首先我們必須明白邏輯處理和物理處理和區(qū)別,邏輯處理是指執(zhí)行一個(gè)查詢應(yīng)該產(chǎn)生什么樣的結(jié)果,那么邏輯查詢的各個(gè)階段就是這個(gè)查詢從邏輯上執(zhí)行的先后順序,依照這個(gè)先后順序就能得到正確的結(jié)果,正如我們做四則混合運(yùn)算一樣,先乘除后加減才能得到正確結(jié)果。

  所以說邏輯查詢只關(guān)心產(chǎn)生一個(gè)我們期望的、正確的結(jié)果,它并不關(guān)心產(chǎn)生這個(gè)結(jié)果需要多少的資源消耗。而物理處理就是怎么得到這個(gè)結(jié)果,這個(gè)時(shí)候才會(huì)考慮性能問題。下面我們就討論下怎么執(zhí)行這個(gè)物理處理的。

  當(dāng)一個(gè)查詢到達(dá)數(shù)據(jù)庫引擎的時(shí)候,數(shù)據(jù)庫引擎需要做的是執(zhí)行這個(gè)查詢的查詢計(jì)劃,那么這個(gè)時(shí)候就存在兩種情況,一種可能是這個(gè)查詢的查詢計(jì)劃已經(jīng)在緩存中,這種情況就直接執(zhí)行這個(gè)查詢計(jì)劃。另外一種情況就是在緩存中找不到該查詢的查詢計(jì)劃。沒有怎么辦?生成一個(gè)!怎么生成?

  執(zhí)行計(jì)劃是在編譯階段生成的,編譯需要經(jīng)過三個(gè)步驟:分析、代數(shù)化(algebrization)、查詢優(yōu)化,看見沒有這里的查詢優(yōu)化過程就能解決上面的朋友提出的先笛卡爾集在篩選造成性能低的問題。下面我就對(duì)這三個(gè)步驟作一個(gè)介紹。

  第一步:分析是檢查語法并把SQL批處理轉(zhuǎn)化成分析樹的過程,如select * t1 where id in(1,2,3,4,5,6,7)在被分析樹分析后就展開成了select * t1 where id=1 or id=2 or id=3 or id=4 or id=5 or id=6 or id=7 ,除此之外還有檢查語法是否正確的功能。

  第二步:接下的過程是代數(shù)化(algebrization),這個(gè)階段使用SQL Server 2005的新組件algebrizer,algebrizer組件的主要功能是綁定,因此代數(shù)化過程通常稱為綁定。這個(gè)階段是將第一步的分析樹作為輸入,生成被稱為查詢處理器樹的輸出,用于查詢優(yōu)化。其實(shí)這個(gè)階段主要做幾個(gè)事情,

  一:運(yùn)算符平展,簡單的講就是把二元運(yùn)算符組合成N元運(yùn)算符,這里必須給出一個(gè)示例才能很好的解釋這個(gè)二元轉(zhuǎn)換成N元如第一步所示in操作展開成了一連串的or運(yùn)算符,而分析器認(rèn)為這些or都是二元的,也就是說它認(rèn)為第一個(gè)or 的左孩子是id=1,右孩子是 (id=2 or id=3 or id=4 or id=5 or id=6 or id=7 )這個(gè)表達(dá)式,而右孩子又被認(rèn)為是二元的,如此一來就必須進(jìn)行一個(gè)遞歸過程。而運(yùn)算符平展過程則將這種二元運(yùn)算組合成n元運(yùn)算符,就避免了遞歸的過程。

  二:名稱解析,這個(gè)過程其實(shí)就是檢查這個(gè)查詢中出現(xiàn)的表或者是表的列是不是在數(shù)據(jù)庫中真實(shí)存在。以及在該查詢過程中是不是可見的。三:類型派生,有點(diǎn)抽象,舉個(gè)例子就能理解了,比如union查詢吧,union左右兩邊查詢結(jié)果對(duì)應(yīng)位置的數(shù)據(jù)類型應(yīng)該是一致的。四:聚合綁定和組分綁定,執(zhí)行完這個(gè)步驟后查詢處理器樹便生成了。

  第三步:查詢優(yōu)化,這個(gè)過程由查詢優(yōu)化器組件來完成的。查詢中應(yīng)該以何種順序訪問表,使用哪種方法和使用哪個(gè)索引,應(yīng)該由哪個(gè)聯(lián)接算法等都是由查詢優(yōu)化器組件來決定的,但是這個(gè)決定也不是隨意的,它必須滿足的前提條件是保證最后得到的結(jié)果集必須是正確的,也就是說該結(jié)果集必須遵循邏輯處理的各個(gè)階段所得到的結(jié)果集相同。優(yōu)化器會(huì)嘗試該查詢的許多變體,一查找成本最低的計(jì)劃。

  如果優(yōu)化器分析該查詢的元數(shù)據(jù)得知只有一個(gè)可執(zhí)行的計(jì)劃,那么它就不會(huì)再嘗試尋求更好的計(jì)劃,這個(gè)步驟叫做細(xì)微計(jì)劃優(yōu)化。如果沒有找到細(xì)微計(jì)劃優(yōu)化,SQL Server將執(zhí)行一些簡化,簡化就是對(duì)自身語法作一些轉(zhuǎn)換,比如在聯(lián)接前計(jì)算表的where篩選器,如前一篇描述的,邏輯查詢中where篩選總是在聯(lián)接之后計(jì)算,但是先計(jì)算where篩選器在聯(lián)接同樣能得到的正確的結(jié)果,而這樣的效率往往是更高的,所以在物理處理中where往往在join前執(zhí)行的,開篇提到的那個(gè)問題只是讀者未理解邏輯處理和物理處理的差別而已。

  到此為止,物理處理的各個(gè)步驟也做了一個(gè)簡要的敘述,總結(jié)下,無論是存儲(chǔ)過程還是即席查詢都是執(zhí)行的一個(gè)查詢計(jì)劃的副本,如果這個(gè)查詢計(jì)劃不存在的話就必須經(jīng)過編譯生成一個(gè)執(zhí)行計(jì)劃,在編譯階段必須經(jīng)過分析,綁定(代數(shù)化),查詢優(yōu)化這些過程,最終得到我們需要查找的結(jié)果。關(guān)于查詢優(yōu)化組件具體是怎么優(yōu)化查詢處理器樹的,我會(huì)在以后的篇幅作詳細(xì)介紹。

關(guān)鍵詞標(biāo)簽:優(yōu)化SQL語句

相關(guān)閱讀

文章評(píng)論
發(fā)表評(píng)論

熱門文章 Oracle中使用alter table來增加,刪除,修改列的語法 Oracle中使用alter table來增加,刪除,修改列的語法 oracle中使用SQL語句修改字段類型-oracle修改SQL語句案例 oracle中使用SQL語句修改字段類型-oracle修改SQL語句案例 誤刪Oracle數(shù)據(jù)庫實(shí)例的控制文件 誤刪Oracle數(shù)據(jù)庫實(shí)例的控制文件 為UNIX服務(wù)器設(shè)置Oracle全文檢索 為UNIX服務(wù)器設(shè)置Oracle全文檢索

相關(guān)下載

    人氣排行 oracle中使用SQL語句修改字段類型-oracle修改SQL語句案例 Oracle中使用alter table來增加,刪除,修改列的語法 ORACLE SQL 判斷字符串是否為數(shù)字的語句 ORACLE和SQL語法區(qū)別歸納(1) oracle grant 授權(quán)語句 ORACLE修改IP地址后如何能夠使用 如何加速Oracle大批量數(shù)據(jù)處理 Oracle刪除表的幾種方法