一、關(guān)聯(lián)子查詢是什么
關(guān)聯(lián)子查詢是指和外部查詢有關(guān)聯(lián)的子查詢,具體來(lái)說(shuō)就是在這個(gè)子查詢里使用了外部查詢包含的列。在關(guān)聯(lián)子查詢中,對(duì)于外部查詢返回的每一行數(shù)據(jù),內(nèi)部查詢都要執(zhí)行一次。另外,在關(guān)聯(lián)子查詢中是信息流是雙向的。外部查詢的每行數(shù)據(jù)傳遞一個(gè)值給子查詢,然后子查詢?yōu)槊恳恍袛?shù)據(jù)執(zhí)行一次并返回它的記錄。然后,外部查詢根據(jù)返回的記錄做出決策。
關(guān)聯(lián)子查詢與嵌套子查詢不同的是,信息傳播是雙向而不是單向的。在嵌套子查詢中,僅處理內(nèi)部查詢一次,并向外部查詢傳遞信息——本質(zhì)上提供相同值或者列出錄入的清單。但是,內(nèi)部查詢利用關(guān)聯(lián)子查詢涉及外部查詢提供的信息,反之亦然。這種說(shuō)法似乎有點(diǎn)令人混淆,但它可以分為三步進(jìn)行處理:
外部查詢得到一條記錄并傳遞到內(nèi)部查詢中;內(nèi)部查詢基于輸入值執(zhí)行;內(nèi)部查詢把返回值輸出到外部查詢中,并用這些值結(jié)束內(nèi)部查詢。二、關(guān)聯(lián)子查詢語(yǔ)法的好處
1、簡(jiǎn)化SQL語(yǔ)句:關(guān)聯(lián)子查詢語(yǔ)法可以將多個(gè)SQL查詢合并成一個(gè)查詢,從而簡(jiǎn)化SQL語(yǔ)句的編寫(xiě)。這樣可以減少代碼量,提高開(kāi)發(fā)效率。
2、提高查詢效率:關(guān)聯(lián)子查詢語(yǔ)法可以避免多次執(zhí)行相同的查詢,從而提高查詢效率。使用關(guān)聯(lián)子查詢可以將兩個(gè)或多個(gè)表的數(shù)據(jù)一次性讀入內(nèi)存中,在內(nèi)部完成數(shù)據(jù)比較,減少對(duì)數(shù)據(jù)庫(kù)的IO操作,提高查詢速度。
3、方便進(jìn)行數(shù)據(jù)分析:關(guān)聯(lián)子查詢可以將多個(gè)表的數(shù)據(jù)合并在一起,方便進(jìn)行數(shù)據(jù)的分析和處理。使用關(guān)聯(lián)子查詢可以更容易地獲取和處理表與表之間的數(shù)據(jù),增強(qiáng)了SQL查詢的靈活性和功能擴(kuò)展性。
4、支持復(fù)雜查詢:關(guān)聯(lián)子查詢可以支持復(fù)雜的查詢需求,如嵌套子查詢、多個(gè)SELECT語(yǔ)句的組合等,從而滿足不同業(yè)務(wù)場(chǎng)景下的需求。
三、關(guān)聯(lián)查詢優(yōu)化
1、外連接小表驅(qū)動(dòng)大表:LEFT JOIN 時(shí),選擇小表作為驅(qū)動(dòng)表, 大表作為被驅(qū)動(dòng)表 。減少外層循環(huán)的次數(shù)。
2、內(nèi)連接驅(qū)動(dòng)表由優(yōu)化器決定:INNER JOIN 時(shí),MySQL會(huì)自動(dòng)將 小結(jié)果集的表選為驅(qū)動(dòng)表 。選擇相信MySQL優(yōu)化策略。
3、被驅(qū)動(dòng)表優(yōu)先創(chuàng)建索引:被驅(qū)動(dòng)表的JOIN字段要?jiǎng)?chuàng)建索引。
4、兩表連接字段類(lèi)型必須一致:兩個(gè)表JOIN字段數(shù)據(jù)類(lèi)型保持絕對(duì)一致。防止自動(dòng)類(lèi)型轉(zhuǎn)換導(dǎo)致索引失效。
5、關(guān)聯(lián)替代子查詢:能夠直接多表關(guān)聯(lián)的盡量直接關(guān)聯(lián),不用子查詢。(減少查詢的趟數(shù))。子查詢是一個(gè)SELECT查詢的結(jié)果作為另一個(gè)SELECT語(yǔ)句的條件。
6、多次查詢代替子查詢:不建議使用子查詢,建議將子查詢SQL拆開(kāi)結(jié)合程序多次查詢,或使用 JOIN 來(lái)代替子查詢。
四、子查詢
子查詢是一種常用計(jì)算機(jī)語(yǔ)言SELECT-SQL語(yǔ)言中嵌套查詢下層的程序模塊。當(dāng)一個(gè)查詢是另一個(gè)查詢的條件時(shí),稱(chēng)之為子查詢。
在SQL語(yǔ)言中,一個(gè)SELECT-FROM-WHERE語(yǔ)句稱(chēng)為一個(gè)查詢塊。當(dāng)獲得一個(gè)查詢的答案需要多個(gè)步驟的操作,首先必須創(chuàng)建一個(gè)查詢來(lái)確定用戶不知道但包含在數(shù)據(jù)庫(kù)中的值,將一個(gè)查詢塊嵌套在另一個(gè)查詢塊的WHERE字句或HAVING短語(yǔ)的條件中查詢塊稱(chēng)為子查詢或內(nèi)層查詢。上層的查詢塊曾為父查詢或外層查詢。子查詢的結(jié)果作為輸入傳遞回“父查詢”或“外部查詢”。父查詢將這個(gè)值結(jié)合到計(jì)算中,以便確定最后的輸出。
SQL語(yǔ)言允許多層嵌套查詢,即一個(gè)子查詢中還可以嵌套其他子查詢。以層層嵌套的方式來(lái)構(gòu)造程序正是SQL中”結(jié)構(gòu)化”的含義所在。子查詢是本質(zhì)上就是一個(gè)完整 的SELECT 語(yǔ)句,它可以使一個(gè) SELECT、SELECT…INTO 語(yǔ)句、INSERT…INTO 語(yǔ)句、DELETE 語(yǔ)句、或 UPDATE 語(yǔ)句或嵌套在另一子查詢中。子查詢的輸出可以包括一個(gè)單獨(dú)的值(單行子查詢)、幾行值(多行子查詢)、或者多列數(shù)據(jù)(多列子查詢)。
延伸閱讀1:WHERE子句中的關(guān)聯(lián)子查詢
在這個(gè)特定的查詢中,外部查詢只在WHERE子句中引用內(nèi)部查詢——它也可以在SELECT清單中包括從內(nèi)部查詢中獲得的數(shù)據(jù)。通常根據(jù)自己的意愿決定是否希望使用別名,但對(duì)關(guān)聯(lián)子查詢,則必須使用別名。這種查詢?cè)诤艽蟪潭壬巷@示了為什么內(nèi)部查詢和外部查詢都建立在同一張表上。兩個(gè)查詢都從彼此之間獲得信息,因此,如果沒(méi)有別名,它們就不會(huì)知道用戶對(duì)哪張表的數(shù)據(jù)感興趣。