日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

 美好生活谷 2019-04-16

一、多表查詢連接的選擇:

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

相信這內(nèi)連接,左連接什么的大家都比較熟悉了,當(dāng)然還有左外連接什么的,基本用不上我就不貼出來(lái)了。這圖只是讓大家回憶一下,各種連接查詢。 然后要告訴大家的是,需要根據(jù)查詢的情況,想好使用哪種連接方式效率更高。

二、MySQL的JOIN實(shí)現(xiàn)原理

在MySQL 中,只有一種Join 算法,就是大名鼎鼎的Nested Loop Join,他沒(méi)有其他很多數(shù)據(jù)庫(kù)所提供的Hash Join,也沒(méi)有Sort Merge Join。顧名思義,Nested Loop Join 實(shí)際上就是通過(guò)驅(qū)動(dòng)表的結(jié)果集作為循環(huán)基礎(chǔ)數(shù)據(jù),然后一條一條的通過(guò)該結(jié)果集中的數(shù)據(jù)作為過(guò)濾條件到下一個(gè)表中查詢數(shù)據(jù),然后合并結(jié)果。如果還有第三個(gè)參與Join,則再通過(guò)前兩個(gè)表的Join 結(jié)果集作為循環(huán)基礎(chǔ)數(shù)據(jù),再一次通過(guò)循環(huán)查詢條件到第三個(gè)表中查詢數(shù)據(jù),如此往復(fù)。 ——摘自《MySQL 性能調(diào)優(yōu)與架構(gòu)設(shè)計(jì)》

三、補(bǔ)充:mysql對(duì)sql語(yǔ)句的容錯(cuò)問(wèn)題

即在sql語(yǔ)句不完全符合書(shū)寫(xiě)建議的情況,mysql會(huì)允許這種情況,盡可能解釋它:

1)一般cross join后面加上where條件,但是用cross join+on也是被解釋為cross join+where;

2)一般內(nèi)連接都需要加上on限定條件,如上面場(chǎng)景一;如果不加會(huì)被解釋為交叉連接;

3)如果連接表格使用的是逗號(hào),會(huì)被解釋為交叉連接;

注:sql標(biāo)準(zhǔn)中還有union join和natural inner join,mysql不支持,而且本身也沒(méi)有多大意義,其實(shí)就是為了“健壯”。但是其實(shí)結(jié)果可以用上面的幾種連接方式得到。

三、超大型數(shù)據(jù)盡可能盡力不要寫(xiě)子查詢,使用連接(JOIN)去替換它:

當(dāng)然,關(guān)于這句話,也不一定就全是這樣。

1)因?yàn)樵诖笮偷臄?shù)據(jù)處理中,子查詢是非常常見(jiàn)的,特別是在查詢出來(lái)的數(shù)據(jù)需要進(jìn)一步處理的情況,無(wú)論是可讀性還是效率上,這時(shí)候的子查都是更優(yōu)。

2)然而在一些特定的場(chǎng)景,可以直接從數(shù)據(jù)庫(kù)讀取就可以的,比如一個(gè)表(A表 a,b,c字段,需要內(nèi)部數(shù)據(jù)交集)join自己的效率必然比放一個(gè)子查在where中快得多。

四、使用聯(lián)合(UNION)來(lái)代替手動(dòng)創(chuàng)建的臨時(shí)表

UNION是會(huì)把結(jié)果排序的?。?!

union查詢:它可以把需要使用臨時(shí)表的兩條或更多的select查詢合并的一個(gè)查詢中(即把兩次或多次查詢結(jié)果合并起來(lái)。)。在客戶端的查詢會(huì)話結(jié)束的時(shí)候,臨時(shí)表會(huì)被自動(dòng)刪除,從而保證數(shù)據(jù)庫(kù)整齊、高效。使用union來(lái)創(chuàng)建查詢的時(shí)候,我們只需要用UNION作為關(guān)鍵字把多個(gè)select語(yǔ)句連接起來(lái)就可以了,要注意的是所有select語(yǔ)句中的字段數(shù)目要想同。

要求:兩次查詢的列數(shù)必須一致(列的類型可以不一樣,但推薦查詢的每一列,相對(duì)應(yīng)的類型要一樣)

可以來(lái)自多張表的數(shù)據(jù):多次sql語(yǔ)句取出的列名可以不一致,此時(shí)以第一個(gè)sql語(yǔ)句的列名為準(zhǔn)。

如果不同的語(yǔ)句中取出的行,有完全相同(這里表示的是每個(gè)列的值都相同),那么union會(huì)將相同的行合并,最終只保留一行。也可以這樣理解,union會(huì)去掉重復(fù)的行。

如果不想去掉重復(fù)的行,可以使用union all。

如果子句中有order by,limit,需用括號(hào)()包起來(lái)。推薦放到所有子句之后,即對(duì)最終合并的結(jié)果來(lái)排序或篩選。

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

注意:

1、UNION 結(jié)果集中的列名總是等于第一個(gè) SELECT 語(yǔ)句中的列名

2、UNION 內(nèi)部的 SELECT 語(yǔ)句必須擁有相同數(shù)量的列。列也必須擁有相似的數(shù)據(jù)類型。同時(shí),每條 SELECT 語(yǔ)句中的列的順序必須相同

UNION ALL的作用和語(yǔ)法:

默認(rèn)地,UNION 操作符選取不同的值。如果允許重復(fù)的值,請(qǐng)使用 UNION ALL。當(dāng) ALL 隨 UNION 一起使用時(shí)(即 UNION ALL),不消除重復(fù)行。

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

五、總結(jié)

(1)對(duì)于要求全面的結(jié)果時(shí),我們需要使用連接操作(LEFT JOIN / RIGHT JOIN / FULL JOIN);

(2)應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

備注、描述、評(píng)論之類的可以設(shè)置為 NULL,其他最好不要使用NULL。

不要以為 NULL 不需要空間,比如:char(100) 型,在字段建立時(shí),空間就固定了, 不管是否插入值(NULL也包含在內(nèi)),都是占用 100個(gè)字符的空間的,如果是varchar這樣的變長(zhǎng)字段, null 不占用空間。

可以在num上設(shè)置默認(rèn)值0,確保表中num列沒(méi)有null值,然后這樣查詢:

select id from t where num = 0

(3)in 和 not in 也要慎用,否則會(huì)導(dǎo)致全表掃描,如:

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

對(duì)于連續(xù)的數(shù)值,能用 between 就不要用 in 了:

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

很多時(shí)候用 exists 代替 in 是一個(gè)好的選擇:

你們要的多表查詢優(yōu)化來(lái)啦!請(qǐng)查收

(4)盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型,這會(huì)降低查詢和連接的性能,并會(huì)增加存儲(chǔ)開(kāi)銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B 接時(shí)會(huì)逐個(gè)比較字符串中每一個(gè)字符,而對(duì)于數(shù)字型而言只需要比較一次就夠了。

(5)盡量使用表變量來(lái)代替臨時(shí)表。如果表變量包含大量數(shù)據(jù),請(qǐng)注意索引非常有限(只有主鍵索引)。

(6)不要以為使用MySQL的一些連接操作對(duì)查詢有多么大的改善,其實(shí)核心是索引


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多