在SQL語(yǔ)言中,一個(gè)SELECT-FROM-WHERE語(yǔ)句稱為一個(gè)查詢塊。將一個(gè)查詢塊嵌入另一個(gè)查詢塊的WHERE子句或HAVING短語(yǔ)的條件中,這" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

18143453325 在線咨詢 在線咨詢
18143453325 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 信息時(shí)代 > 嵌套子查詢的優(yōu)化(數(shù)據(jù)庫(kù))

嵌套子查詢的優(yōu)化(數(shù)據(jù)庫(kù))

時(shí)間:2022-11-06 22:30:01 | 來(lái)源:信息時(shí)代

時(shí)間:2022-11-06 22:30:01 來(lái)源:信息時(shí)代

    嵌套子查詢的優(yōu)化 : 優(yōu)化嵌套查詢語(yǔ)句,選擇合理的查詢計(jì)劃。
在SQL語(yǔ)言中,一個(gè)SELECT-FROM-WHERE語(yǔ)句稱為一個(gè)查詢塊。將一個(gè)查詢塊嵌入另一個(gè)查詢塊的WHERE子句或HAVING短語(yǔ)的條件中,這種查詢稱為嵌套查詢。例如查詢借閱過(guò)書(shū)名以“計(jì)算機(jī)”開(kāi)頭的借閱者姓名,可以如下表示:
SELECT name /*外層查詢或父查詢*/
FROM BR WHERE bookno IN
(SELECT bookno /*內(nèi)層查詢或子查詢*/
FROM BOOK
WHERE bname like'計(jì)算機(jī)');
在這個(gè)例子中,下層查詢塊SELECT bookno FROM BOOK WHERE bname like '計(jì)算機(jī)'是嵌套在上層查詢塊SELECT name FROM BR WHERE bookno IN的WHERE條件中的。上層的查詢塊稱為外層查詢或父查詢,下層查詢塊稱為內(nèi)層查詢或子查詢。SQL語(yǔ)言允許多層嵌套查詢,即一個(gè)子查詢中還可以嵌套其他子查詢。
嵌套查詢分為相關(guān)嵌套子查詢和不相關(guān)嵌套子查詢。當(dāng)子查詢的查詢條件中沒(méi)有引用父查詢中的屬性,即子查詢條件不依賴于父查詢,這種嵌套子查詢稱為不相關(guān)子查詢。上面的例子就是一個(gè)不相關(guān)子查詢的例子。
對(duì)于不相關(guān)子查詢,由于子查詢條件中沒(méi)有引用父查詢的屬性,因此子查詢可以獨(dú)立求出。不相關(guān)子查詢的求解方法是由里向外逐層處理。具體地,有兩類處理方法。
第一類處理方法是針對(duì)僅以比較運(yùn)算符構(gòu)造父查詢條件的不相關(guān)子查詢。這類查詢的特點(diǎn)是,子查詢有唯一取值。假設(shè)要查詢與DB一書(shū)在同一個(gè)出版社出版的書(shū)目,由于DB只在一個(gè)出版社出版過(guò),因此,可以用等號(hào)構(gòu)造父查詢條件。
SELECT bname
FROM BOOK
WHERE publishing_house=(SELECT publishing_house
FROM BOOK
WHERE bname='DB');
對(duì)于這種僅以比較運(yùn)算符構(gòu)成父查詢條件的不相關(guān)子查詢,可以作為兩個(gè)獨(dú)立的查詢進(jìn)行優(yōu)化,求解時(shí)由里向外處理,即先執(zhí)行子查詢,子查詢的結(jié)果用于建立其父查詢的查找條件。例如對(duì)于上例,首先求解出出版DB一書(shū)的出版社,不妨假設(shè)是“機(jī)械工業(yè)出版社”,然后將其值代入父查詢,求解“機(jī)械工業(yè)出版社”出版的所有圖書(shū)。
第二類處理方法是針對(duì)其他不相關(guān)子查詢的,查詢優(yōu)化器將其重寫(xiě)為連接查詢。由于子查詢可以獨(dú)立求解,因此用子查詢結(jié)果構(gòu)成一張臨時(shí)表T,將嵌套查詢重寫(xiě)為父查詢的關(guān)系與T的連接操作。例如對(duì)于前面查詢借閱過(guò)書(shū)名以“計(jì)算機(jī)”開(kāi)頭的借閱者姓名的例子,首先求解子查詢,找出以“計(jì)算機(jī)”開(kāi)頭的所有圖書(shū)的編號(hào),構(gòu)成臨時(shí)表T,然后將BR表和T表進(jìn)行自然連接,得出查詢結(jié)果。這一查詢重寫(xiě)過(guò)程是在邏輯優(yōu)化時(shí)完成的,物理優(yōu)化時(shí)即可按照普通查詢的物理優(yōu)化進(jìn)行。
如果子查詢的查詢條件依賴于父查詢,這類子查詢稱為相關(guān)子查詢(correlated subquery)。例如查詢劉婧借閱過(guò)的所有圖書(shū),可以如下表達(dá):
SELECT bname
FROM BOOK
WHERE EXISTS
(SELECT*
FROM BR
WHERE bookno=BOOK.bookno
AND name='劉婧');
這就是一個(gè)相關(guān)子查詢,概念上,我們可以在BOOK中依次取每條元組的bookno值,用此值去檢查BR表。若BR中存在這樣的元組,其bookno值等于此BOOK.bookno值,并且其name='劉婧',則取此BOOK.bname送入結(jié)果表。
相關(guān)嵌套查詢的執(zhí)行效率往往不高,因?yàn)閷?duì)外層查詢的每一條元組都要運(yùn)行一次子查詢,從而可能導(dǎo)致大量的隨機(jī)磁盤I/O操作。因此,SQL優(yōu)化器盡可能重寫(xiě)查詢,將嵌套子查詢轉(zhuǎn)換成連接查詢,通過(guò)有效的連接算法來(lái)避免昂貴的隨機(jī)I/O操作。這與不相關(guān)嵌套子查詢的第二種情況類似。
例如,上面的相關(guān)嵌套查詢語(yǔ)句可以重寫(xiě)為下面的連接查詢:
SELECT bname
FROM BOOK,BR
WHERE BR.bookno=BOOK.bookno
AND name='劉婧');
這個(gè)例子中的嵌套子查詢非常簡(jiǎn)單。一般情況下,不能將嵌套子查詢關(guān)系直接移入外層查詢的FROM子句里,而是采用與不相關(guān)嵌套子查詢的第二種情況類似的方法,建立一個(gè)包含嵌套查詢結(jié)果的臨時(shí)表,將這個(gè)臨時(shí)表與外層查詢進(jìn)行連接。例如,下面形式的查詢:
SELECT …
FROM R
WHERE Predl AND exists
(SELECT*
FROM S
WHERE Pred2)
其中Pred2是一組簡(jiǎn)單謂詞的合取,可以重寫(xiě)為:
CREATE table T AS
SELECT distinct Related_Var
FROM S
WHERE Pred2_unrelated;

SELECT …
FROM R,T
WHERE Predl AND Pred2_related;
這里的Pred2 unrelated包含Pred2中所有不涉及相關(guān)變量的條件,Pred2 related是所有涉及相關(guān)變量的條件(條件中引用的關(guān)系會(huì)相應(yīng)地重命名),Related Var是嵌套子查詢的相關(guān)變量。
對(duì)于查詢劉婧借閱過(guò)的所有圖書(shū)的嵌套查詢例子,該嵌套查詢可轉(zhuǎn)換為如下形式:
CREAT TABLE T AS
SELECT DISTINCT bookno
FROM BR WHERE name='劉婧';
SELECT bname
FROM BOOK,T
WHERE T.bookno=BOOK.bookno;
這種用連接查詢(可能使用臨時(shí)關(guān)系)去替代嵌套查詢的過(guò)程稱為去除相關(guān)。去除相關(guān)是嵌套查詢優(yōu)化的主要技術(shù)。為去除相關(guān)進(jìn)行的查詢重寫(xiě)是在邏輯優(yōu)化過(guò)程中完成。但并不是所有相關(guān)嵌套查詢都能很容易地去除相關(guān),重寫(xiě)為連接查詢。在無(wú)法轉(zhuǎn)換的情況下,優(yōu)化器只能將子查詢當(dāng)作一個(gè)獨(dú)立的表達(dá)式進(jìn)行優(yōu)化,然后再進(jìn)行相關(guān)執(zhí)行。
顯然,復(fù)雜嵌套子查詢的優(yōu)化是非常困難的。目前許多DBMS產(chǎn)品的查詢優(yōu)化器僅做了少量的去除相關(guān)工作,因此用戶最好避免使用復(fù)雜的嵌套子查詢。

74
73
25
news

版權(quán)所有? 億企邦 1997-2022 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉