面試準備之mysql知識點介紹

目錄

 

1.mysql索引

1.索引類型

2.索引的好處和壞處

4.爲什麼索引結構是B+樹,而不是平衡樹或者是B樹或者是hash表

5.innerdb和myisam的索引

6.索引的好處和壞處

3.Mysql的鎖

1.表鎖和行鎖

2.共享鎖和排他鎖

3.間隙鎖

3.Mysql的事物

4.Mysql的優化


1.mysql索引

1.索引類型

聚集索引和輔助索引,輔助索引可以分爲唯一索引,普通索引,全文索引
聚集索引和輔助索引的區別是聚集索引和數據存放的邏輯順序是一致的,這樣用聚集索引進行範圍查找就會很快
聚集索引和唯一索引的區別就是
1.聚集索引和唯一索引的值都是唯一的,
2.一個表中的只有一個聚集索引,可以有多個唯一索引,
3.唯一索引的值可以是null,但是聚集索引的值不能是null,
4.聚集索引的順序和數據存放的物理順序是一致的,唯一索引索引順序和數據存放的物理順序有可能不一致。
普通索引:是在一個列或者多列數據上創建了索引,這些列的值可以重複也可以爲null。
全文索引:全文索引有自己匹配方式,在mysql5.6以前,只有myisam支持全文索引,在5.6之後myisam和innerdb都支持全局索引。全局索引只支持的字段是char,varcha和text,而且全局索引有最小搜索長度的限制。
所用全局索引的查詢的sql
select * from test where match(content) against('aaa’);
覆蓋索引:覆蓋索引是當我們查詢的出來的列都在同一個索引裏面的時候就是覆蓋索引,這樣只需要查詢索引文件就可以查詢出想要的結果,不需要回表查詢。
創建索引的sql:
創建聚集索引  alter table test add primary key('id');
創建唯一索引  alter table test add unique('phone');
創建普通索引  alter table test add index('name');
創建全文索引  alter table test add fulltext('content’);
創建多咧索引  alter table test add index(‘class','school’);
刪除索引: alter table test drop index ’name’;
 

2.索引的好處和壞處

索引的好處:
1.加快查詢,因爲索引的數據結構可以幫我們還快查詢速度。
2.可以保證數據的唯一性,如果是聚集索引或者是唯一索引,可以保證這個列的數據在整個表裏面是唯一的。
3.索引可以加快表與表直接的連接。
4.使用分組和排序的時候如果用到了索引,可以減少分組和排序的時間
索引的壞處:
1.維護索引需要額外的開銷,當對數據頻繁進行增刪改的時候,爲了維護索引的結構,有可能需要對索引進行重新排序。
2.索引需要額外的存儲空間來存儲。
 
3.索引的數據結構
在myisam和innerdb裏面,索引的數據接口是B+樹,而memory裏面是hash表
B樹的特點是如果是n介B樹的話
1.非葉子結點裏面存儲的都是關鍵字,葉子結點裏面存儲的是關鍵字和數據
2.所有葉子結點都在同一層。
3.左子樹的關鍵字都小於節點裏面的值,右子樹裏面的關鍵字都大於節點裏面的值
如果是N階B+樹的話,非跟節點,一個節點裏面最多有n-1個關鍵字,也就是最多有n個子樹,最少有n/2-1個關鍵字,也就是最少有n/2個子樹。
4.而且葉子結點是空的。
B+樹和B樹最大的不同就是
B+樹的非葉子結點裏面存儲的只是關鍵字,而B樹的結點裏面存儲的是關鍵字和數據,B樹的葉子結點都是空的
B+樹的葉子結點是一個雙向鏈表結構
B+樹的結點裏面有幾個關鍵字,那麼就有幾顆子樹。
 

4.爲什麼索引結構是B+樹,而不是平衡樹或者是B樹或者是hash表

       如果用hash表結構的話,如果是等值查詢的話,使用hash表的索引確實要快一些,但是hash表不支持範圍查詢的,不能利用索引的來排序。hash表不支持最左前綴原則。hash表也不能支持模糊查詢。hash表等值查詢雖然要快一些,但是不穩定,因爲當某些值大量重複的時候,會發生hash碰撞,這樣會導致查詢變慢。
       平衡樹一個節點裏面只能存儲一個關鍵字,當表很大的時候,這個樹的高度會很大,會造成多次I/O,而且平衡樹不支持範圍查找。爲什麼樹的高度會和I/O次數有關,I/O從硬盤將數據讀取到內存一次應該能讀取很多數據,但是根據平衡樹的左右子樹選址的話,一次能確定獲取的數據就是左子樹結點或右子樹結點,至於下面的結點那就只能看運氣了,如果再想往下一層獲取數據的話,可能又得根據左右子樹的指針來I/O一次了。但是如果使用B+樹作爲索引結構,它的非葉子結點都存儲的是關鍵字,所以一個節點能存放很多關鍵字,導致B+樹的高度大大降低,它的I/O次數會明顯減少。
       B樹雖然一個節點能存儲很多關鍵字,但是每個節點裏面也會存儲數據,這回導致一個節點裏面存儲關鍵字能力要小於B+樹,所以B樹的高度要大於B+樹,而且B樹不支持範圍查找。
總結起來的話:使用B+樹的好處 :查找效率穩定   支持範圍查找    IO次數更少
 

5.innerdb和myisam的索引

相同點
innerdb和myisam都是使用B+樹來作爲索引存儲結構
不同點
innerdb裏面的聚集索引和數據都是在同一個文件裏面的,innerdb的聚集索引的B+樹葉子結點裏面存儲的不僅有索引的關鍵字,還帶有完整的數據。
myisam的聚集索引和數據是分離的,myisam的聚集索引的葉子節點裏面存儲的是索引關鍵字和這個數據的地址。
innerdb的輔助索引的葉子結點裏面存儲的是聚集索引的關鍵字。所以如果用innerdb的輔助索引查找的話會經過兩次遍歷B+樹的經歷。
myisamd的輔助索引的葉子結點裏面存儲的是這個數據的地址,所以myisam使用輔助索引來查找數據的話經過一次就能查找到,我想這也是爲什麼當查詢過多的時候可以選擇myisam存儲引擎,因爲如果用輔助索引的話只需要遍歷一次就能查找到,減少了I/O次數。
 

6.索引的好處和壞處

好處
1.索引能加快查詢速度。
2.索引能加快表與表的之間的連接。
3.索引能加快排序和分組。
4.聚集索引或者唯一索引能保證數據的唯一性。
壞處
1.當數據修改或者刪除的時候需要維護索引,增加系統開銷
2.索引會佔用大量的存儲空間
2.InnerDB和MyIsam的的不同點
1.InnerDB支持事務,MyIsam不支持事務。
2.InnerDB支持表鎖和行鎖,MyIsam只支持表鎖。
3.InnerDB支持外健,MyIsam不支持外健。
4.InnerDB聚集索引和數據是在一起的,聚集索引葉子結點裏面存儲的是完整的數據,輔助索引葉子結點存儲的是聚集索引的值。MyIsam聚集索引和非聚集索引的的葉子結點存儲的都是一樣的,是數據的記錄地址。
5.Myisam存儲的有表記錄的總數,而InnerDB是沒用存儲的,所以當InnerDB通過
select count(*) from table 的時候會全表查詢,而MyIsam是不想要的。
6.MyIsam可以不需要主鍵,但InneDB一定需要主鍵,如果InnerDB如果沒有主鍵,它會自己給自己生存一個。
7.MyIsam支持全文索引,InnerDB在5.7版本後也支持全文索引。
8.Innodb存儲文件有frm、ibd,而Myisam是frm、MYD、MYI
   Innodb:frm是表定義文件,ibd是數據文件
   Myisam:frm是表定義文件,myd是數據文件,myi是索引文件
 

3.Mysql的鎖

1.表鎖和行鎖

按照鎖的級別來分,分爲表鎖和行鎖
表鎖:加鎖快,開銷小,加鎖力度大,不會造成死鎖,但是併發度低,容易造成鎖衝突
行鎖:加鎖慢,開銷大,加鎖力度大,會造成死鎖,併發度高,造成鎖衝突的概率低
 
 
按照鎖的特徵分,分爲共享鎖(讀鎖)和排他鎖(寫鎖)
當前session對錶或者行加了共享鎖後,其他session也能加共享鎖,但會禁止本session和其他session加排他鎖。
當前session對錶或者行加排他鎖後,其他session不能加共享鎖也不能加排他鎖和共享鎖。
 
由於MyIsam只支持表鎖,所以的加的也是表級共享鎖和表級排他鎖。
 

2.共享鎖和排他鎖

顯示加鎖解鎖方法:
排他鎖
lock table tablename write;    
unlock tables;
 
select ……. lock in share mode
共享鎖
lock table tablename read;
unlock tables;
 
select ….. for update
 

3.間隙鎖

當使用排他鎖或者是共享鎖的時候,如果對帶有索引的列進行的不是等值查詢而是用範圍進行查詢的話,那麼鎖定的不止是數據庫裏面存在滿足條件的記錄,還會鎖住數據庫裏面不存在但也滿足條件的記錄
舉個例子,數據庫裏有id 是1,2,3,4,5 五條記錄,並在這個id上有索引,當
select * from table where id>3 for update;  這個sql鎖住的是id爲4,5還有id 大於5的記錄,雖然這些記錄不在數據庫裏。
 
MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作 (UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖。
但是在加了表級共享鎖後,還是可以併發插入數據的,
如果是lock table table name read local; 其中local就是在滿足條件下准許在併發插入
當concurrent_insert設置爲0時,不允許併發插入。
當concurrent_insert設置爲1時,如果MyISAM表中沒有空洞(即表的中間沒有被刪除的行),MyISAM允許在一個進程讀表的同時,另一個進程從表尾插入記錄。這也是MySQL的默認設置。
當concurrent_insert設置爲2時,無論MyISAM表中有沒有空洞,都允許在表尾併發插入記錄。
 
InnerDB的話由於是支持行鎖的,所以可以給某一行加共享鎖和排他鎖
update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,
如果加排他鎖可以使用select …for update語句,
加共享鎖可以使用select … lock in share mode語句。
所以加過排他鎖的數據行在其他事務種是不能修改數據的,也不能通過for update和lock in share mode鎖的方式查詢數據,但可以直接通過select …from…查詢數據,因爲普通查詢沒有任何鎖機制。
InnoDB行鎖是通過給索引上的索引項加鎖來實現的,這一點MySQL與Oracle不同,後者是通過在數據塊中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特點意味着:只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!mysql InnoDB引擎默認的修改數據語句:update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,如果加排他鎖可以使用select …for update語句,加共享鎖可以使用select … lock in share mode語句。所以加過排他鎖的數據行在其他事務種是不能修改數據的,也不能通過for update和lock in share mode鎖的方式查詢數據,但可以直接通過select …from…查詢數據,因爲普通查詢沒有任何鎖機制。
可以通過檢查InnoDB_row_lock狀態變量來分析系統上的行鎖的爭奪情況:
show status like 'innodb_row_lock%';
 
 
 

3.Mysql的事物

 
mysql的事物默認是開啓的,也就是執行一條sql就是一個事物,查看事物是否開啓
show variables like ‘autocommit'
如果要關閉事物的提交,就需要  set autocommit = 0;
 
事物是數據庫執行的一個單元,裏面有一個或者多個sql,要麼全部執行要麼全部不執行
事物的四大特性就是ACID,也就是原子性,一致性,隔離性和持久性。
原子性:事物裏面的所有操作可以看作是一個整體,要麼全部成功,要麼全部失敗,如果前面的成功了,後面的失敗了,則前面成功的需要會滾。事物的原子性原理是靠undo日誌來維持的,當對數據進行修改的時候,會生成相應的undo log,如果事物執行失敗或者發生回滾,則需要利用undo log將數據恢復到以前的樣子。以update作爲例子,undo log需要記錄被修改的主鍵,確認有哪些列都被修改了,記錄被修改前後的值,回滾的時候就可以利用這些信息將數據還原。
一致性:將數據庫從一種狀態改成另外一種狀態,數據庫裏面的數據執行前後都是合法的,數據庫的數據要保持完整性。原子性,持久性和隔離性都是爲了保持一致性。
持久性:事物對數據的修改並提交後,就是永久性的改變,及時數據庫發生了崩潰,這個更改也是存在的。持久性實現原理是redo log。innerdb爲了減少IO次數,有一個緩衝池,取數據的時候會先從緩衝池裏面取,如果緩衝池裏面沒有數據,就會從磁盤裏面取,然後放入到緩衝池裏面。修改數據的時候也是先寫入到緩衝池中,如果緩衝池裏面,然後再寫進到磁盤中,但如果當寫入到緩衝池但還沒有寫到磁盤裏面發生宕機後,就會導致數據丟失。在修改數據的時候會先寫到redo log裏面,再寫入緩衝池中,所以在事物提交的時候,會先將redo log寫入硬盤中。這樣在發生宕機的時候,就可以讀取redo log進行日誌恢復了。其實總結起來就是:在修改數據的時候會先用redo log記錄修改的數據,然後再來修改數據,當提交數據的時候會先將redo log存入到硬盤中。
隔離性:就是兩個事物併發執行,其中一個事物對數據的更改不會影響到另一個事物對數據的執行,兩個事物之間不會產生干擾。但是由於隔離級別設置的不同,所以導致兩個事物執行的時候會產生不同的影響。
 
(一個事務)寫操作對(另一個事務)寫操作的影響:鎖機制保證隔離性
(一個事務)寫操作對(另一個事務)讀操作的影響:MVCC保證隔離性
MVCC即多版本控制,可以讓不同的事物在同一時刻看到的數據不一樣。它最大的好處是讀寫不衝突,併發性能好,這是在我們的數據行都隱藏有三個字段,分別是創建時間段,刪除時間段和回滾指針,即指向undo log的指針。其中創建時間段存儲的是這行數據被創建時的事物版本號,刪除時間段指的是這行數據被更改或者刪除的事物版本號,可以通過undo log做回滾操作查看之前的數據。
MVCC查詢事物的兩個原則
1.查詢的數據的創建版本號要小於等於當前版本號。
2.查詢的數據的刪除版本號要大於當前版本號或者爲空。
 
最後總結一下事物的原理:
原子性是利用undo log,當發生回滾的時候利用修改時所留下來的undo log進行數據恢復
持久性時利用redo log,當數據修改被寫入緩衝池中的時候,會先將修改用redo log記錄下來。
隔離性利用數據庫鎖機制和mvcc機制來進行數據隔離的判斷。
 
 

4.Mysql的優化

最主要的優化就是sql優化
1.開啓慢查詢,查看慢查詢裏面查詢過慢的sql
2.使用explain對sql進行分析,看是否使用索引,掃描的行數和使用索引的類型以及查詢中有回表查詢
3.注意讓mysql索引失效的一些操作和能讓mysql加快查詢的一些操作。
4.如果數據太多的話,就分區分表了。
5.如果還是比較慢的話可以用show  processlist 查看,看看有可能是連接數過多,或者有很多sleep時間過長的線程,或者有出現鎖等待過長的線程,可以進行殺掉。或者查看waittime的設定值,show variables like “%timeout%”;修改這個值來減少連接
6.查看鎖衝突的情況,看是否發現死鎖或者鎖衝突的情況很多show status like 'innodb_row_lock%';
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章