欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

這篇文章將為大家詳細(xì)講解有關(guān)MySQL同樣邏輯的四種SQL寫(xiě)法分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

創(chuàng)新互聯(lián)-專(zhuān)業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性?xún)r(jià)比赤峰網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式赤峰網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋赤峰地區(qū)。費(fèi)用合理售后完善,十年實(shí)體公司更值得信賴(lài)。

提到復(fù)雜查詢(xún),MYSQL 頭疼的旅程就開(kāi)始了,當(dāng)然優(yōu)化的方法和其他的數(shù)據(jù)監(jiān)控也不大同,MYSQL的語(yǔ)句優(yōu)化屬于發(fā)散性思維,只要你能用上的方法都可以,可不限制于數(shù)據(jù)庫(kù)本身的語(yǔ)句優(yōu)化。所以MYSQL的優(yōu)化好像是一個(gè)講不完的故事。

下面舉一個(gè)列子看看同時(shí)達(dá)到同樣結(jié)果的不同的語(yǔ)句的寫(xiě)法,產(chǎn)生的性能結(jié)果有什么不同

現(xiàn)在有兩個(gè)表一個(gè)department 表 一個(gè) 員工與部門(mén)之間的關(guān)聯(lián)表  dept_emp

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

現(xiàn)在由于部門(mén)裁撤,要統(tǒng)計(jì)哪些部門(mén)現(xiàn)在還有員工,將有員工的部門(mén)顯示出來(lái)。

當(dāng)然不提表的結(jié)構(gòu)和行數(shù)的性能比較都是屬于耍流氓

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

下面是兩種寫(xiě)法

select em.dept_name

from (select distinct dept_no from dept_emp) as de

inner join departments as em on em.dept_no = de.dept_no;

select distinct em.dept_name 

from dept_emp as de 

inner join departments as em on em.dept_no = de.dept_no;

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

從上圖的分析來(lái)看

select em.dept_name

from (select distinct dept_no from dept_emp) as de

inner join departments as em on em.dept_no = de.dept_no;

的寫(xiě)法要優(yōu)于

select distinct em.dept_name 

from dept_emp as de 

inner join departments as em on em.dept_no = de.dept_no;

在有相關(guān)的索引的加持下,在查詢(xún)中先將重復(fù)的數(shù)據(jù)進(jìn)行去重后,在進(jìn)行關(guān)聯(lián)的方法要明顯比,先關(guān)聯(lián)在去重的方法要好。

那到此就完結(jié)了,有么有其他的寫(xiě)法,下面就是另一種寫(xiě)法

select em.dept_name

from departments as em 

inner join (

select de.dept_no_d from (select distinct dept_no as dept_no_d from dept_emp) as de  where de.dept_no_d in (select dept_no from departments)) as tm on em.dept_no = tm.dept_no_d  ;

同樣能達(dá)到同樣的結(jié)果,看上去復(fù)雜的寫(xiě)法,其實(shí)也并不慢

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

那我們是否還有其他的寫(xiě)法,或者讓剛才的方式的查詢(xún)變得更快

select distinct de.dept_name from departments as de where exists (select 1 from dept_emp em where de.dept_no = em.dept_no);

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

最后我們將所有的四種寫(xiě)法,執(zhí)行一遍,通過(guò)profile 對(duì)比一下四種方法的快慢和消耗

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

從上面的分析看,最次的是使用in來(lái)進(jìn)行查詢(xún),而最好的是用exists 的方式來(lái)進(jìn)行查詢(xún), 使用  JOIN 的方法屬于中規(guī)中矩。

但在分析這四種查詢(xún)的方法,以及產(chǎn)生的不同效果中,可以看到

select distinct de.dept_name from departments as de where exists (select 1 from dept_emp em where de.dept_no = em.dept_no);

select distinct em.dept_name 

    -> from dept_emp as de 

    -> inner join departments as em on em.dept_no = de.dept_no;

兩種方法在選擇的索引以及執(zhí)行計(jì)劃都有類(lèi)似的地方,為什么使用exists的子查詢(xún)?cè)谶@里要快于使用join的方式

MYSQL同樣邏輯的四種SQL寫(xiě)法分析

可以看到雖然語(yǔ)句的執(zhí)行計(jì)劃相同,但不同的是慢的那個(gè)使用了Using temporary, 也就是二次處理了搜尋上來(lái)的結(jié)果,進(jìn)行了一個(gè)去重的工作,而快的exists 則沒(méi)有這個(gè)操作。

那問(wèn)題就來(lái)了,不是說(shuō)子查詢(xún)慢嗎,子查詢(xún)是如何進(jìn)行查詢(xún)的,但實(shí)際上為什么在這個(gè)例子不慢。

MySQL子查詢(xún)是從外部到內(nèi)部評(píng)估查詢(xún)。也就是說(shuō),它首先獲取外層表達(dá)式的值,然后運(yùn)行子查詢(xún)并捕獲它生成的行。對(duì)于子查詢(xún)有用的優(yōu)化是“通知”子查詢(xún),只有內(nèi)部表達(dá)式的條件等于外部表達(dá)式的那些行才可以進(jìn)行優(yōu)化,將一個(gè)適當(dāng)?shù)牡仁较峦频阶硬樵?xún)的WHERE子句中來(lái)實(shí)現(xiàn)的。

寫(xiě)法如下

EXISTS (SELECT 1 FROM ... WHERE  外部條件=內(nèi)部條件)

我們例子中的寫(xiě)法快的那個(gè)恰恰和這個(gè)寫(xiě)法相同,在轉(zhuǎn)換之后,MySQL可以使用下推等式來(lái)限制它必須檢查的行數(shù)來(lái)計(jì)算子查詢(xún),記得之前寫(xiě)過(guò)一篇關(guān)于 ICP 的文字,這里就不說(shuō) 下推的問(wèn)題了。

說(shuō)到這里要實(shí)現(xiàn)ICP 還要有一個(gè)條件就是,不能有NULL 值,也就是空值, 所以這也是 DBA 費(fèi)盡心機(jī)的 和 開(kāi)發(fā)人員溝通,說(shuō)你的這個(gè)字段盡量不要有NULL最好有 DEFAULT  默認(rèn)值的一個(gè)原因,因?yàn)槟悴恢篮螘r(shí)因?yàn)槟愕淖侄卫锩娉跗谠O(shè)計(jì)的有NULL 值,就造成費(fèi)盡心機(jī)的優(yōu)化半途而廢。

如果有NULL 值結(jié)果就是

EXISTS (SELECT 1 FROM ... WHERE  外部條件=內(nèi)部條件 or 內(nèi)部條件 is NUll)

當(dāng)然這也沒(méi)有什么,MYSQL 遇到NULL 不走索引的,我也曾經(jīng)寫(xiě)過(guò)一篇,辟謠了。

問(wèn)題是 or 這個(gè)操作您的另外進(jìn)行一個(gè)表操作的問(wèn)題,另外還有無(wú)法在ICP 下推了,主要的原因是NULL 在數(shù)據(jù)庫(kù)里面并不是FALSE 而是未知的狀態(tài),ICP 下推必須要進(jìn)行適當(dāng)?shù)挠?jì)算,必須能夠檢查SELECT是否已經(jīng)產(chǎn)生了任何行,這樣內(nèi)部條件 = 外部條件就不能下推到子查詢(xún)中。

所以這也是為什么人家子查詢(xún)不慢,你的慢的一個(gè)因素,不要認(rèn)為查詢(xún)寫(xiě)的一樣,結(jié)果就一樣,各種前期不注意的地方,就能坑你一下。

關(guān)于MYSQL同樣邏輯的四種SQL寫(xiě)法分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

標(biāo)題名稱(chēng):MYSQL同樣邏輯的四種SQL寫(xiě)法分析
轉(zhuǎn)載來(lái)源:http://chinadenli.net/article26/pgoocg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)網(wǎng)站排名、網(wǎng)站導(dǎo)航標(biāo)簽優(yōu)化、軟件開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)