close

點擊上方「Java基基」,選擇「設為星標」

做積極的人,而不是積極廢人!

每天14:00更新文章,每天掉億點點頭髮...

源碼精品專欄

原創 | Java 2021超神之路,很肝~

中文詳細注釋的開源項目

RPC 框架 Dubbo 源碼解析

網絡應用框架 Netty 源碼解析

消息中間件 RocketMQ 源碼解析

數據庫中間件 Sharding-JDBC 和 MyCAT 源碼解析

作業調度中間件 Elastic-Job 源碼解析

分布式事務中間件 TCC-Transaction 源碼解析

Eureka 和 Hystrix 源碼解析

Java 並發源碼

來源:juejin.im/post/

5e0443ae6fb9a0162277a2c3

送分題
再談SQL Join
回顧
緩衝區
一個大前提
Join算法
總結
送分題

面試官 :有操作過Linux嗎?

我 :有的呀

面試官 :我想查看內存的使用情況該用什麼命令

我 :free 或者 top

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

我 :那,如下圖所示 可以看到內存以及緩存的使用情況

total 總內存
used 已用內存
free 空閒內存
buff/cache 已使用的緩存
avaiable 可用內存

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

我 :em... 不知道

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

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

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

基於 Spring Boot + MyBatis Plus + Vue & Element 實現的後台管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能。

項目地址:https://github.com/YunaiV/ruoyi-vue-pro

再談SQL Join

面試官 :換個話題,談談你對join的理解

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

回顧

SQL中的join可以根據某些條件把指定的表給結合起來並將數據返回給客戶端

join的方式有

inner join 內連接
left join 左連接
right join 右連接
full join 全連接

以上圖片源自這裡

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

我 :分為兩種情況,數據規模小的,數據規模大的。

面試官 : 然後?

我 :對於

數據規模較小 全部干進內存就完事了嗷
數據規模較大

可以通過增加索引來優化join語句的執行速度 可以通過冗餘信息來減少join的次數 儘量減少表連接的次數,一個SQL語句表連接的次數不要超過5次

面試官 :可以總結為join語句是相對比較耗費性能,對嗎?

我 :是的

面試官 : 為什麼?

緩衝區

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

面試官 : 是的

我 :逐條比較兩個表的語句是比較慢的,因此我們可以把兩個表中數據依次讀進一個內存塊中, 以MySQL的InnoDB引擎為例,使用以下語句我們必然可以查到相關的內存區域show variables like '%buffer%'

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

面試官 : 除此之外呢?

一個大前提

我 :任何項目終究要上線,不可避免的要產生數據,數據的規模又不可能太小

面試官 : 是這樣的

我 :大部分數據庫中的數據最終要保存到硬盤上,並且以文件的形式進行存儲。

以MySQL的InnoDB引擎為例

InnoDB以頁(page)為基本的IO單位,每個頁的大小為16KB
InnoDB會為每個表創建用於存儲數據的.ibd文件

驗證

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

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

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

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

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

圖片來源這裡

面試官 : 你有沒有想過

buff/cache 裡面存的是什麼,?
為什麼buff/cache 占了那麼多內存,可用內存即availlable還有1.1G?
為什麼你可以通過兩條命令來清理buff/cache占用的內存,而想要釋放used只能通過結束進程來實現?

品,你細品

思考了幾分鐘後

我 :這麼隨便就釋放了buff/cache所占用的內存,說明它就不重要, 清除它不會對系統的運行造成影響

面試官 : 不完全對

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

存儲器層次結構的本質是,每一層存儲設備都是較低一層設備的緩存

翻譯成人話,就是說Linux會把內存當作是硬盤的高速緩存

相關資料 tldp.org/LDP/sag/htm…

面試官 :現在知道那道送分題應該怎麼回答了吧

我 :我....

Join算法

面試官 :再給你個機會,如果讓你來實現Join算法你會怎麼做?

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

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

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

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

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

Nested Loop Join

嵌套循環,每次只讀取表中的一行數據,也就是說如果outerTable有10萬行數據, innerTable有100行數據,需要讀取10000000次(假設這兩個表的文件沒有被操作系統給緩存到內存, 我們稱之為冷數據表)

當然現在沒啥數據庫引擎使用這種算法(太慢了)

Block nested loop

Block 塊,也就是說每次都會取一塊數據到內存以減少I/O的開銷

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

考慮以下兩個表 t_a 和t_b

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

基於微服務的思想,構建在 B2C 電商場景下的項目實戰。核心技術棧,是 Spring Boot + Dubbo 。未來,會重構成 Spring Cloud Alibaba 。

項目地址:https://github.com/YunaiV/onemall

總結

上學時,數據庫老師最喜歡考數據庫範式,直到上班才學會一切以性能為準,能冗餘就冗餘,實在冗餘不了的就join如果join真的影響到性能。試着調大你的join_buffer_size, 或者換固態硬盤。

歡迎加入我的知識星球,一起探討架構,交流源碼。加入方式,長按下方二維碼噢:

已在知識星球更新源碼解析如下:

最近更新《芋道 SpringBoot 2.X 入門》系列,已經 101 余篇,覆蓋了MyBatis、Redis、MongoDB、ES、分庫分表、讀寫分離、SpringMVC、Webflux、權限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能測試等等內容。

提供近 3W 行代碼的 SpringBoot 示例,以及超 6W 行代碼的電商微服務項目。

獲取方式:點「在看」,關注公眾號並回復666領取,更多內容陸續奉上。

文章有幫助的話,在看,轉發吧。

謝謝支持喲 (*^__^*)

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()