mysql索引底層的資料結構是b+樹
為什麼不採用二叉查詢樹/紅黑樹?
二叉查詢樹和紅黑樹的每個結點只能存放乙個索引值,每個節點只能有兩個分叉。即使紅黑樹能夠自平衡,在資料非常龐大的情況下,也會導致樹的高度非常的高,而樹的高度每增加一層,就意味著要多進行一次io操作,io操作非常的耗時,便會導致查詢的速度變慢。
為什麼不採用b樹?
b+樹是b樹的變體,不同的是,非葉子節點只拿來存放索引,資料都儲存在葉子節點中,所有的葉子節點之間存在雙向指標。由於索引占用的空間大小遠小於資料所佔的空間大小,這也就意味著b+樹的非葉子節點能夠存放更多的索引,所以其葉子結點能夠存放更多的資料。其次由於b+樹的所有葉子結點均有下乙個鏈指標指向下乙個結點,所以在範圍查詢上有著明顯的優勢,這也就是mysql採用b+樹而不採用b樹的原因
為什麼優先採用b+樹而不採用hash索引
對於精準查詢,hash索引的檢索速度明顯快於b+樹,但對於範圍查詢,hash索引基本是全表掃瞄,而b+樹的葉子之間存在著雙向指標,查詢效率快,所以總的來說優先採用b+樹
密集索引與稀疏索引
密集索引:所謂密集索引,就是索引跟資料存放在乙個檔案,也就是葉子結點存放的資料便是真真實實的資料
兩大儲存引擎myisam與innodb在索引上的區別
innodb:
innodb預設採用的是密集索引,進入c:\programdata\mysql\mysql server 5.5\data\atm,可以看到資料與索引是統一存放在.ibd檔案裡面
innodb有且只有乙個密集索引
為什麼innodb表必須有主鍵,並且推薦主鍵用整型自增長?
對於innodb,若乙個主鍵被定義,則主鍵則作為密集索引,若沒有主鍵被定義,該錶的第乙個唯一非空的字段則作為密集索引,若不滿足以上條件,innodb內部會生成乙個隱藏主鍵(密集索引),所以這便會浪費mysql的資源。推薦主鍵用整型是因為b+樹進行比較時,相比uuid可以提高比較速度,而使用自增長則可以減少b+tree在插入資料時的調整次數。
myisam:
myisam預設採用的是稀疏索引,進入c:\programdata\mysql\mysql server 5.5\data\atm,可以看到索引存放在myi檔案,而資料存放在myd檔案
myisam不管是主鍵索引,唯一鍵索引還是普通索引都是稀疏索引
最左匹配原則
1.mysql會一直右匹配直到遇到範圍查詢(>、5 and d=6 如果建立(a,b,c,d)順序的索引,d是用不到索引,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整
2.=和in可以亂序,比如a=1 and b=2 and c=3 建立(a,b,c)索引可以任意順序,mysql的查詢優化器會幫你優化成索引可以識別的形式,但假如是 b = 2 and c = 3就用不到索引了
鎖的分類
按鎖的粒度劃分,可分為表級鎖,行級鎖,頁級鎖
按鎖的級別劃分,可分為共享鎖(讀鎖),排他鎖(寫鎖)
上了讀鎖再上讀鎖是可以的,上讀鎖再上寫鎖或者上寫鎖再上讀/寫鎖都是阻塞的
myisam和innodb在鎖方面區別
myisam:
預設採用表級鎖,不支援行級鎖(所以myisam一般適用於頻繁的全表查詢操作)
對於select語句上的讀鎖,對於update insert delete上的是寫鎖
innodb:
innodb預設採用的是行級鎖(走索引),也支援表級鎖(不走索引)(所以innodb一般使用頻繁的增刪改查操作)
innodb對select做了改進,對於select語句是不上鎖的,若要對select上讀鎖則要select......lock in share mode,若要對select上寫鎖則select...... for update;對於update insert delete上的是寫鎖
資料庫事務的四大特性
a(原子性):要麼全部執行,要不全部不執行
c(一致性):轉賬前後的數值加起來應該是一致的
i (隔離性):重點
d(永續性):對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾
事務的隔離級別
read uncommited(讀未提交):出現髒讀,不可重複度,幻讀
read commmited(讀已提交):避免髒讀,出現不可重複讀,幻讀
repreatable read(可重複讀):避免了髒讀,不可重複讀,出現幻讀(理論上,repreatable read是無法避免幻讀的,但是mysql的innodb卻避免了幻讀的問題)
serializable(序列化):避免了髒讀,不可重複讀,幻讀,相當於鎖表
innodb的rr級別如何避免幻讀
當前讀與快照讀:
當前讀(讀取最新的資料):select......lock in share mode ,select.....for update, update,delete,insert
快照讀(可能讀取到歷史版本):不加鎖的非阻塞讀,select
1.對於快照讀,rr級別如何避免幻讀是基於mvcc實現的
對於資料行裡都隱藏有db_trx_id(事務操作id)、db_roll_ptr(回滾指標)、db_row_id(主鍵),這樣對於資料行的操作通過回滾指標連線起來形成多個版本,對於歷史版本都記錄到了undo日誌。read committed和repeatable read隔離級別來說,都需要讀取已經提交的事務所修改的記錄,也就是說如果版本鏈中某個版本的修改沒有提交,那麼該版本的記錄時不能被讀取的。對於read committed來說,每次read view都建立快照,所以讀取的都是最新事務提交的資料行;而對於repeatable read來說,read view的時間相當關鍵,因為它只建立一次快照,以後的每次read view都只用這個快照。也正因為這樣,在repeatable read隔離級別下,使用快照讀(即普通的select)實現重複讀,又能避免幻讀。
2.對於當前讀,rr級別如何避免幻讀是基於gap鎖實現
2.1在走主鍵索引和唯一性索引的當前讀中
如果where條件全部命中,則不會用gap鎖,只會加行鎖。(因為主鍵索引跟唯一性索引是唯一的,無法重複插入,故而沒必要加gap鎖)
如果where條件部分命中或者不命中,則會加gap鎖(因為where沒有全部命中,沒命中部分可能在另外乙個事務會進行插入,所以必須要加gap鎖)
2.2在走非唯一索引或者不走索引的當前讀中
如果走非唯一性索引,會加gap鎖(因為非唯一性索引是非唯一的,可以重複插入,所以需要加gap鎖)
如果不走索引,則相當於鎖表了,相比表鎖這種上鎖表的代價更大,所以要盡量避免
mysql索引與鎖的關係 關係型資料庫 索引與鎖
設計乙個關係型資料庫 png 索引模組 為什麼要使用索引 查詢時間複雜度從o n 提公升到o logn png 存在以下弊端,並且會多次io,影響速度。png 採用b tree b tree 多路搜尋樹,並不是二叉的 是一種常見的資料結構。使用b tree結構可以顯著減少定位記錄時所經歷的中間過程,...
資料庫索引,事務與鎖
目錄事務和鎖 行鎖 select from 表名 where id 1 for update 排他鎖,上鎖之後,其他使用者對這個表的增刪改查就回阻塞,等你操作完成之後,其他使用者才能操作 select from table name where lock in share mode 共享鎖 其他使用...
mysql資料庫鎖 MySQL資料庫的鎖機制
在併發訪問情況下,很有可能出現不可重複讀等等讀現象。為了更好的應對高併發,封鎖 時間戳 樂觀併發控制 樂觀鎖 悲觀併發控制 悲觀鎖 都是併發控制採用的主要技術方式。鎖分類 按操作劃分 dml鎖,ddl鎖 按鎖的粒度劃分 表級鎖 行級鎖 頁級鎖 按鎖級別劃分 共享鎖 排他鎖 按加鎖方式劃分 自動鎖 顯...