分為兩個模組。第一是儲存(檔案系統);第二是程式例項(儲存管理、快取機制、sql解析、日誌管理、許可權劃分、容災機制、索引管理、鎖管理)
快速查詢資料,避免全表掃瞄
主鍵、唯一鍵以及普通鍵等
生成索引,建立二叉查詢樹進行二分查詢
生成索引,建立b-tree(b樹)結構進行查詢
❤生成索引,建立b+-tree結構(b+樹)進行查詢:資料都儲存在葉子節點中;葉子節點彼此相連,方便作範圍統計
生成索引,建立hash結構進行查詢
question:為什麼b+樹更適合做儲存索引?
answer:
b+樹的磁碟讀寫代價更低(b+樹內部沒有指向關鍵字具體資訊的指標,只有索引資訊,資料都放在葉子節點)
b+樹的查詢效率更加穩定(每個資料都要到葉子節點中查詢資料,效率大致相同 o(logn))
b+樹更有利於對資料庫的掃瞄(資料都存放在葉子節點中)
根據慢日誌定位慢查詢sql:
show variables like '%quer%';
設定是否開啟慢查詢日誌slow_query_log=on;設定慢查詢時間long_query_time=1
執行完查詢語句如果時間超過1秒,則記錄在慢日誌中
使用explain等工具分析sql:
在慢查詢語句之前加入explain關鍵字,分析語句
explain關鍵字段:
type:如果出現了index或者all,可能就需要優化了
extra:
using filesort:對結果在記憶體或磁碟上進行排序,無法利用索引排序
using temporary:對查詢結果排序時使用臨時表,常見於order by和group by
修改sql或者盡量讓sql走索引:
可以給列加index索引
最左字首匹配原則,mysql會一直向右匹配知道遇到範圍查詢(>、<、between、like)就停止匹配。
mysql會對聯合索引最左邊的字段進行排序,在這個基礎上,對第二個索引字段進行排序。
(一般第乙個索引字段絕對有序,第二個索引字段無序,所以要對第二個字段進行條件判斷,用不到索引)
資料量小的表不需要建立索引,建立會增加額外的索引開銷
資料變更需要維護索引,因此更多的索引意味著更多的維護成本
更多的索引意味著需要更多的空間
共享鎖:讀鎖(s鎖),共享鎖就是多個事務對於同一資料可以共享一把鎖,都能訪問到資料,但是只能讀不能修改。
排他鎖:寫鎖(x鎖),排他鎖就是不能與其他鎖並存,如乙個事務獲取了乙個資料行的排他鎖,其他事務就不能再獲取該行的其他鎖,包括共享鎖和排他鎖,但是獲取排他鎖的事務是可以對資料就行讀取和修改。
mysql innodb引擎的update、insert、delete語句會自動給涉及到的資料加上排它鎖,select語句預設不加任何鎖。
mysql myisam引擎的update、insert、delete語句會自動給全表上寫鎖,select語句會給全表上讀鎖。
select ... for update 加排它鎖
select ... lock in share mode 加共享鎖
x + x = 衝突(上了排它鎖就不能上其他鎖)
x + s = 衝突(上了排它鎖就不能上其他鎖)
s + x = 衝突(排它鎖不能與其他鎖共存)
s + s = 相容
myisam預設表級鎖(只支援表級鎖),inoodb預設行級鎖(也支援表級鎖)。
myisam適合場景:
頻繁執行全表count語句(myisam會把表的count屬性放進乙個變數中);
對資料進行增刪改的頻率不高,查詢非常頻繁(因為增刪改會鎖表);
沒有事務
inoodb適合場景:
資料增刪改查都相當頻繁;
可靠性要求比較高,要求支援事務
表級鎖、行級鎖、頁級鎖
共享鎖、排它鎖
自動鎖(insert、update、delete)、顯式鎖(for update、lock in share mode)
dml鎖(處理資料的時候進行加鎖)、ddl鎖(更改表結構的時候加鎖)
樂觀鎖:會在提交資料的時候,對資料的衝突與否進行檢測,如果衝突了,返回給使用者錯誤的資訊,讓使用者決定如何做(不會利用資料庫提供的鎖機制)。
一般實現方式:記錄資料版本 --> 1)記錄資料版本號(增加version列欄位,每次更新成功加1) 2)使用時間戳
悲觀鎖:每次資料操作都會上排它鎖,悲觀併發控制也是先取鎖後訪問(利用資料庫本身的鎖機制),額外開銷大,效率較慢,增加產生死鎖的機會。
原子性(事務包含的操作要麼全部執行,要麼全部回滾)
一致性(a+b=2000,無論ab怎麼操作,最後相加的資料都是2000)
隔離性(多個事務併發執行時,乙個事務的執行不應該影響其他事務的執行)
永續性(恢復已提交事務的更新)
事務讀取到了其他事務未提交的資料
解決:提高事務隔離級別read committed
乙個事務多次重複讀取某行資料,可以得到的結果是不一樣(因為有其他事務在更新資料),如果對舊資料進行操作,會出現問題
解決:提高事務隔離級別repeatable read(inoodb預設隔離級別)
事務a執行了當前讀操作,事務b在這個範圍內,插入了一條資料,事務a再次進行當前讀操作,會出現更新行數不正確的問題
解決:提高事務隔離級別serializable(這個級別下,每個操作都會預設加讀鎖/寫鎖)
當前讀(加了鎖的增刪改查):select...lock in share mode/for update、update、delete、insert
快照讀(不加鎖的非阻塞讀):select
表象:快照讀 -- 偽mvcc
內在:next-key鎖(行鎖+gap鎖)
注:gap鎖(間隙鎖),鎖定乙個範圍但不包括記錄本身,防止同一事務的兩次當前讀出現幻讀的情況;gap鎖會用在非唯一索引或者不走索引的當前讀中
question:對主鍵索引或者唯一索引會用gap鎖嗎?
answer:
如果where條件全部命中,則不會用gap鎖,只會加記錄鎖
如果where條件部分命中或者全不命中,則會加gap鎖(鎖的是乙個範圍)
資料行裡的db_trx_id(最新一次對本行記錄做修改的事務的識別符號)、db_roll_ptr(回滾指標)、db_row_id(行號)
undo日誌(對資料進行變更操作就會產生undo記錄,記錄舊版本資料)
read view(判斷當前事務能看到的是哪個版本的資料)
注:rc下快照讀每次都會生成乙個新的快照,所以資料都是最新;rr下,會記錄歷史版本,會選擇第一次快照讀的資料
Java 面試之資料庫
資料庫事務是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。事務滿足以下四大特性 原子性 atomicity 乙個事務中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾到事務開始前的狀態。一致性 consistency 在...
java面試之mysql資料庫
1.資料庫引擎 mysql常用的資料庫引擎有兩種,一種是innodb,發音為 in no db 一種是 myisam,發音為 my z ei m innodb引擎提供了對資料庫acid事務支援,並實現四種隔離級別和行級鎖和外來鍵約束,myisam沒有提供對資料庫事務的支援,也不支援行級鎖和外來鍵,但...
java面試 資料庫索引全面解析
資料庫中查詢操作非常普遍,索引就是提公升查詢速度的一種手段。b 樹索引 它就是傳統意義上的索引,它是最常用 最有效的索引。雜湊索引 雜湊索引是一種自適應的索引,資料庫會根據表的使用情況自動生成雜湊索引,我們人為是沒辦法干預的。rtree索引 在mysql很少使用,僅支援geometry資料型別 相對...