為什么代碼規(guī)范要求SQL語句不要過多的join考赛?

作者: 柯三

juejin.im/post/5e0443ae6fb9a0162277a2c3

送分題

面試官:有操作過Linux嗎?

我:有的呀

面試官:我想查看內(nèi)存的使用情況該用什么命令

我:free 或者 top

面試官:那你說一下用free命令都可以看到啥信息

我:那颜骤,如下圖所示 可以看到內(nèi)存以及緩存的使用情況

  • total 總內(nèi)存

  • used 已用內(nèi)存

  • free 空閑內(nèi)存

  • buff/cache 已使用的緩存

  • avaiable 可用內(nèi)存

image

面試官:那你知道怎么清理已使用的緩存嗎(buff/cache)

我:em… 不知道

面試官:sync; echo 3 > /proc/sys/vm/drop_caches就可以清理buff/cache了忍抽,你說說我在線上執(zhí)行這條命令做好不好?

image

我:(送分題,內(nèi)心大喜)好處大大的有,清理出緩存我們就有更多可用的內(nèi)存空間, 就跟pc上面xx衛(wèi)士的小火箭一樣鸠项,點一下祟绊,就釋放出好多的內(nèi)存

面試官:em…., 回去等通知吧

再談SQL Join

面試官:換個話題,談?wù)勀銓oin的理解

我:好的(再答錯就徹底完了嘉熊,把握住機會)

回顧

SQL中的join可以根據(jù)某些條件把指定的表給結(jié)合起來并將數(shù)據(jù)返回給客戶端

join的方式有

inner join 內(nèi)連接

image

left join 左連接

image

right join 右連接

image

full join 全連接

image

圖片來源:https://www.cnblogs.com/reaptomorrow-flydream/p/8145610.html

面試官:在項目開發(fā)中如果需要使用join語句,如何優(yōu)化提升性能?

我:分為兩種情況呼巴,數(shù)據(jù)規(guī)模小的衣赶,數(shù)據(jù)規(guī)模大的厚满。

**面試官: **然后?

我:對于

1.數(shù)據(jù)規(guī)模較小 全部干進內(nèi)存就完事了嗷

2.數(shù)據(jù)規(guī)模較大

  • 可以通過增加索引來優(yōu)化join語句的執(zhí)行速度

  • 可以通過冗余信息來減少join的次數(shù)

  • 盡量減少表連接的次數(shù),一個SQL語句表連接的次數(shù)不要超過5次

面試官:可以總結(jié)為join語句是相對比較耗費性能遵馆,對嗎货邓?

我:是的

**面試官: **為什么?

緩沖區(qū)

**我: **在執(zhí)行join語句的時候必然要有一個比較的過程

面試官: 是的

我:逐條比較兩個表的語句是比較慢的四濒,因此我們可以把兩個表中數(shù)據(jù)依次讀進一個內(nèi)存塊中, 以MySQL的InnoDB引擎為例,使用以下語句我們必然可以查到相關(guān)的內(nèi)存區(qū)域show variables like '%buffer%'

image

如圖所示join_buffer_size的大小將會影響我們join語句的執(zhí)行性能

**面試官: **除此之外呢?

一個大前提

我:任何項目終究要上線戈二,不可避免的要產(chǎn)生數(shù)據(jù)觉吭,數(shù)據(jù)的規(guī)模又不可能太小

**面試官: **是這樣的

我:大部分數(shù)據(jù)庫中的數(shù)據(jù)最終要保存到硬盤上,并且以文件的形式進行存儲仆邓。

以MySQL的InnoDB引擎為例

  • InnoDB以頁(page)為基本的IO單位伴鳖,每個頁的大小為16KB

  • InnoDB會為每個表創(chuàng)建用于存儲數(shù)據(jù)的.ibd文件

image

驗證

image

我:這意味著我們有多少表要連接就需要讀多少個文件,雖然可以利用索引闷游,但還是免不了頻繁的移動硬盤的磁頭

面試官:也就是說頻繁的移動磁頭會影響性能對吧

我:是的,現(xiàn)在的開源框架不都喜歡說自己通過順序讀寫大大的提升了性能嗎休吠,比如hbase业簿、kafka

面試官:說的沒錯,那你認為Linux有對此做出優(yōu)化嗎?提示柜思,你可以再執(zhí)行一次free命令看一下

我:奇怪緩存怎么占用了1.2G多

image

image

圖片來源:https://www.linuxatemyram.com/

面試官:你有沒有想過

  • buff/cache 里面存的是什么赡盘?

  • 為什么buff/cache 占了那么多內(nèi)存陨享,可用內(nèi)存即availlable還有1.1G钝腺?

  • 為什么你可以通過兩條命令來清理buff/cache占用的內(nèi)存,而想要釋放used只能通過結(jié)束進程來實現(xiàn)?

品定硝,你細品

思考了幾分鐘后

image

我:這么隨便就釋放了buff/cache所占用的內(nèi)存喷斋,說明它就不重要, 清除它不會對系統(tǒng)的運行造成影響

**面試官: **不完全對

我:難道是蒜茴?想起來《CSAPP》(深入理解計算機系統(tǒng))里面說過一句話

存儲器層次結(jié)構(gòu)的本質(zhì)是,每一層存儲設(shè)備都是較低一層設(shè)備的緩存

image

通俗來說顽腾,就是說Linux會把內(nèi)存當作是硬盤的高速緩存

相關(guān)資料:http://tldp.org/LDP/sag/html/buffer-cache.html

面試官:現(xiàn)在知道那道送分題應(yīng)該怎么回答了吧

我:我….

image

Join算法

面試官:再給你個機會抄肖,如果讓你來實現(xiàn)Join算法你會怎么做?

我:無索引的話,嵌套循環(huán)就完事了嗷漓摩。有索引的話,則可以利用索引來提升性能.

面試官:說回join_buffer 你認為join_buffer里面存儲的是什么?

我:在掃描過程中管毙,數(shù)據(jù)庫會選擇一個表把他要返回以及需要進行和其他表進行比較的數(shù)據(jù)放進join_buffer

面試官:有索引的情況下是怎么處理的?

我:這個就比較簡單了啃炸,直接讀取兩個表的索引樹進行比較就完事了嗷卓舵,我這邊介紹一下無索引的處理方式

Nested Loop Join

image

嵌套循環(huán)掏湾,每次只讀取表中的一行數(shù)據(jù),也就是說如果outerTable有10萬行數(shù)據(jù), innerTable有100行數(shù)據(jù)筑公,需要讀取10000000次(假設(shè)這兩個表的文件沒有被操作系統(tǒng)給緩存到內(nèi)存, 我們稱之為冷數(shù)據(jù)表)

當然現(xiàn)在沒啥數(shù)據(jù)庫引擎使用這種算法(太慢了)

Block nested loop

image

Block 塊砚嘴,也就是說每次都會取一塊數(shù)據(jù)到內(nèi)存以減少I/O的開銷

當沒有索引可以使用的時候际长,MySQL InnoDB 就會使用這種算法

考慮以下兩個表 t_a 和t_b

image

當無法使用索引執(zhí)行join操作的時候工育,InnoDB會自動使用Block nested loop 算法

image

總結(jié)

上學時搓彻,數(shù)據(jù)庫老師最喜歡考數(shù)據(jù)庫范式,直到上班才學會一切以性能為準怔接,能冗余就冗余扼脐,實在冗余不了的就join如果join真的影響到性能。試著調(diào)大你的join_buffer_size, 或者換固態(tài)硬盤瓦侮。

參考資料

《深入理解計算機系統(tǒng)》- 第6章 存儲器層次結(jié)構(gòu)
《Experiments and fun with the Linux disk cache》作者通過幾個例子來說明硬盤緩存對程序執(zhí)行性能的影響
《Linux ate my ram》 Free參數(shù)的解釋
How to clear the buffer/pagecache (disk cache) under Linux 文章開頭送分題命令的解釋
MySQL 是怎樣運行的:從根兒上理解 MySQL
Block bested loop 來自MariaDB官方文檔解釋了Block-Nested-Loop算法的實現(xiàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市党觅,隨后出現(xiàn)的幾起案子又兵,更是在濱河造成了極大的恐慌逆皮,老刑警劉巖剿牺,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件接箫,死亡現(xiàn)場離奇詭異,居然都是意外死亡随夸,警方通過查閱死者的電腦和手機墨礁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來风科,“玉大人臀蛛,你說我怎么就攤上這事≡チ欤” “怎么了舔琅?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長囱稽。 經(jīng)常有香客問我二跋,道長,這世上最難降的妖魔是什么吞获? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任各拷,我火速辦了婚禮闷营,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚊荣。我一直安慰自己莫杈,他們只是感情好,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布媳叨。 她就那樣靜靜地躺著糊秆,像睡著了一般议双。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汞舱,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天昂芜,我揣著相機與錄音赔蒲,去河邊找鬼。 笑死欢际,一個胖子當著我的面吹牛母市,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播损趋,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼窒篱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了舶沿?” 一聲冷哼從身側(cè)響起墙杯,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎括荡,沒想到半個月后高镐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡畸冲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了算行。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片州邢。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖呀枢,靈堂內(nèi)的尸體忽然破棺而出笼痛,到底是詐尸還是另有隱情摘刑,我是刑警寧澤泣侮,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布活尊,位于F島的核電站蛹锰,受9級特大地震影響铜犬,放射性物質(zhì)發(fā)生泄漏癣猾。R本人自食惡果不足惜纷宇,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桩砰。 院中可真熱鬧硼莽,春花似錦沉删、人聲如沸矾瑰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至磨取,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凫岖,已是汗流浹背哥放。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工甥雕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留犀农,地道東北人呵哨。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像挨务,于是被迫代替她去往敵國和親谎柄。 傳聞我的和親對象是個殘疾皇子朝巫,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 這篇文章主要涉及到MySQL的知識點: 索引(包括分類及優(yōu)化方式潮孽,失效條件往史,底層結(jié)構(gòu)) sql語法(join椎例,un...
    一根薯條閱讀 2,699評論 0 8
  • 系統(tǒng)層面(基本不用動凰棉,看了下撒犀,買的云服務(wù)器基本都已經(jīng)優(yōu)化過了) 內(nèi)核相關(guān)參數(shù)(/etc/sysctl.conf) ...
    神奇大葉子閱讀 1,997評論 0 4
  • --- layout: post title: "如果有人問你關(guān)系型數(shù)據(jù)庫的原理,叫他看這篇文章(轉(zhuǎn))" date...
    藍墜星閱讀 780評論 0 3
  • 原文《MySQL實戰(zhàn)45講》 前言 ? 在實際生產(chǎn)中映凳,關(guān)于 join 語句使用的問題诈豌,一般會集中在以下兩類: ...
    灰氣球閱讀 1,639評論 0 0
  • 基礎(chǔ) 1. 游戲編程高級進階書籍推薦:http://www.douban.com/doulist/522861/ ...
    Kaima_Chen閱讀 3,866評論 2 20