SQL中的join可以根據(jù)某些條件把指定的表給結(jié)合起來并將數(shù)據(jù)返回給客戶端
- inner join 內(nèi)連接 只返回滿足條件的數(shù)據(jù)
- left join 左連接 左外連接,只返回滿足左表的數(shù)據(jù)【左表數(shù)據(jù)全部會顯示
- right join 右連接 右外連接,只返回滿足右表的數(shù)據(jù)【右表數(shù)據(jù)全部會顯示】
- full join 全連接 返回左表和右表所有數(shù)據(jù)
如果需要使用join語句,如何優(yōu)化提升性能?
分為兩種情況,數(shù)據(jù)規(guī)模小的,數(shù)據(jù)規(guī)模大的。
- 數(shù)據(jù)規(guī)模較小 全部干進(jìn)內(nèi)存就完事了嗷
- 數(shù)據(jù)規(guī)模較大:可以通過增加索引來優(yōu)化join語句的執(zhí)行速度 可以通過冗余信息來減少join的次數(shù) 盡量減少表連接的次數(shù),一個SQL語句表連接的次數(shù)不要超過5次.
join語句是相對比較耗費(fèi)性能
執(zhí)行join語句的時候必然要有一個比較的過程,
- 逐條比較兩個表的語句是比較慢的,因此我們可以把兩個表中數(shù)據(jù)依次讀進(jìn)一個內(nèi)存塊中, 以MySQL的InnoDB引擎為例,使用以下語句我們必然可以查到相關(guān)的內(nèi)存區(qū)域show variables like '%buffer%'
- join_buffer_size的大小將會影響我們join語句的執(zhí)行性能。
- 大部分?jǐn)?shù)據(jù)庫中的數(shù)據(jù)最終要保存到硬盤上,并且以文件的形式進(jìn)行存儲。以MySQL的InnoDB引擎為例,
(InnoDB以頁(page)為基本的IO單位,每個頁的大小為16KB,InnoDB會為每個表創(chuàng)建用于存儲數(shù)據(jù)的.ibd文件)這意味著我們有多少表要連接就需要讀多少個文件,雖然可以利用索引,但還是免不了頻繁的移動硬盤的磁頭,頻繁的移動磁頭會影響性能。
Linux 優(yōu)化
Linux會把內(nèi)存當(dāng)作是硬盤的高速緩存(存儲器層次結(jié)構(gòu)的本質(zhì)是,每一層存儲設(shè)備都是較低一層設(shè)備的緩存)join也是使用
join_buffer來緩存數(shù)據(jù):
join_buffer 你認(rèn)為join_buffer里面存儲的是什么?
在掃描過程中,數(shù)據(jù)庫會選擇一個表把他要返回以及需要進(jìn)行和其他表進(jìn)行比較的數(shù)據(jù)放進(jìn)join_buffer
有索引的情況下是怎么處理的
- 直接讀取兩個表的索引樹進(jìn)行比較就完事了;
無索引情況處理 - 嵌套循環(huán)讀取,但是每次讀取Block 塊,也就是說每次都會取一塊數(shù)據(jù)到內(nèi)存以減少I/O的開銷,當(dāng)沒有索引可以使用的時候,MySQL InnoDB 就會使用這種算法。