Mysql - 某邦面試題

1.MySql邏輯架構

			   | 客戶端
  ____________\|/_____________
 |  ________________________  |
 | |________連接____________| |---客戶端通過連接服務,
 |  ______	  ______________  |   將要執行的sql指令傳輸過來
 | |      |	 | 解析sql      | |
 | | 	  |	 |--------------| |
 | | 	  |	 | 預處理       | |
 | | 	  |	 |--------------| |
 | | 緩存 |	 | 查詢優化器   | |---服務器解析並優化sql,
 | | 	  |	 |--------------| |   生成最終的執行計劃並執行
 | | 	  |	 | 生成執行計劃 | |
 | | 	  |	 |--------------| |
 | | 	  |	 |    執行      | |
 | |______|	 |______________| |
 |	________________________  |
 | |                        | |
 | |       存儲引擎         | |---存儲引擎:負責數據的儲存和提取
 | |________________________| |
 |____________________________|

2.鎖

|
|-實現方式劃分 |--樂觀鎖,通常用於數據競爭不激烈的場景,多讀少寫,通過版本號和時間戳實現
|             |--悲觀鎖,通常用於數據競爭激烈的場景,每次操作都會鎖定數據
|
|-影響範圍分  |--表鎖,鎖定整張表,開銷最小,但是會加劇鎖競爭
|            |--行鎖,鎖定行級別,開銷最大,但是可以最大程度的支持併發
|            |  MVCC是行級鎖的變種,多數情況下避免了加鎖操作,開銷更低
|            |  MVCC是通過保存數據的某個時間點快照實現的

3.事務隔離級別(事務內和事務間可見性)

|
|--未提交讀:(Read UnCommitted),事務中的修改,即使沒提交對其他事務也是可見的
|                              事務可能讀取未提交的數據,造成髒讀
|
|--提交讀:(Read Committed),一個事務開始時,只能看見已提交的事務所做的修改
|                          也叫不可重複讀,同一個事務多次讀取同樣記錄可能不同
|
|--可重複讀:(RepeatTable Read),同一個事務中多次讀取同樣的記錄結果時結果相同
|
|--可串行化:Serializable),最高隔離級別,強制事務串行執行

4.存儲引擎

|
|--InnoDB引擎,最重要,使用最廣泛的存儲引擎。被用來設計處理大量短期事務,具有高性能和自動崩潰恢復的特性
|
|--MyISAM引擎,不支持事務和行級鎖,崩潰後無法安全恢復

5.性能優化

|
|--Schema和數據類型優化 |---數據類型|----(Unsigned)TinyInt,SmallInt,MediumInt,Int,BigInt
|                      |           |----Float,Double,Decimal;VarChar,Char(適合存儲固定長度的字符串,如MD5值),Blob,Text 
|                      |           |----DateTime,TimeStamp
|                      |
|                      |---優化建議:儘量使用對應的數據類型。比如,不要用字符串類型保存時間,用整型保存IP。
|                   
|--索引|---作用:過濾(filter),排序或分組(sort/group),覆蓋(cover)                   
|      |---原則:MySql只能高效的利用索引的最左前綴列
|      |
|      |---特點|----大部分情況下,索引都比較小,可以加載在內存中;
|      |	   |----當使用覆蓋索引時,可以避免很多的磁盤操作,因此對性能也會有極大的改善
|      |
|      |---按物理存儲劃分:非聚集索引,聚集索引(葉子節點中存放的即爲整張表的行記錄數據,通過雙向鏈表進行維護表數據邏輯上的連續)
|      |
|      |---類型|----主鍵索引:alert table tablename add primary key (`字段名`)
|      | 按使用|----唯一索引: alter table tablename add unique key (`字段名`);    |-----單列索引
|      |  劃分 |----普通索引: alter table tablename add index (`字段名`);---------|-----多列索引
|      |       |----全文索引: alter table tablename add FULLTEXT(`字段名`);       |     包含特殊索引:覆蓋索引
|      |       |
|      |       |----索引查詢:show indexes from `表名`; 或 show keys from `表名`;
|      |       |----索引刪除:alter table `表名` drop index 索引名;

聚集索引

|
|特點:聚集索引不一定是主鍵,主鍵默認聚集的,所以是聚集索引;表必須有聚集索引,可以沒有主鍵;
|
|-innodb引擎的聚集索引 |
|					  |--有主鍵,那麼這個主鍵就是作爲聚集索引
|					  |--沒有主鍵,那麼該表的第一個唯一非空索引被作爲聚集索引
|					  |--沒有主鍵也沒有合適的唯一索引,那麼innodb內部會生成一個隱藏的主鍵作爲聚集索引,
|					  |				  這個隱藏的主鍵是一個6個字節的列,該列的值會隨着數據的插入自增。

一個使用索引的基本查詢的工作流

|
|--step1. 使用索引以查找匹配的記錄,並得到數據的指針
|--step2. 使用相關數據的指針
|--step3. 返回查詢到的記錄
|
|--當可以使用覆蓋索引時,索引將會覆蓋查詢中的所有字段,因此第二步將會被跳過,於是查詢流程就變成了下面這樣:
|--step1. 使用索引以查找匹配的記錄
|--step2. 返回查詢到的記錄(因爲所有的記錄都在內存中)

6.索引優化案例

|
|--單個等於查詢  |---SELECT * FROM t WHERE c = 100;
|				|---//給c字段創建索引
|				|---SELECT c1, c2 FROM t WHERE c = 100  
|				|---//創建一個(c,c1,c2)的索引,因爲這樣是覆蓋索引(注意不是創建(c1,c2,c))
|				
|--多個等於查詢  |---SELECT * FROM t WHERE c = 100 and d = 'xyz';
|				|---//創建索引(c,d)或(d,c)
|				|---//最常見的錯誤是建立兩個索引:一個是c,一個是d。
|				|---//儘管MySQL根據index_merge算法能同時使用這兩個索引,但這樣依然是糟糕的選擇
|
|--等於與不等於並存的查詢   |---SELECT * FROM t WHERE c > 100 and d = 'xyz';
|						  |---//只要有一列使用了不等於計算,那麼它將阻止<其他列>使用索引
|						  |---//創建一個(d,c)的索引,這時候c和d兩個條件都會走索引
|						  
|--多個不等於查詢  |---SELECT * FROM t WHERE c > 100 and b < 10 and d = 'xyz';
|				  |---//定要把等於條件(在這裏是d)所在列,放在索引的最左側;(創建索引(d,b)或是索引(d,c))
|				  |---//還可以:按照字段b分區(partition on b),然後創建索引(d,c);
|				  |---//或按照字段c分區(partition onc),然後創建索引(d,b)
|				  
|--多個等於與排序  |---SELECT * FROM t WHERE c = 100 and d = 'xyz' ORDER BY b;
|                 |---//索引中字段的順序必須:先過濾後排序;創建(c,d,b)或(d,c,b)
|				  |---SELECT c1, c2 FROM t WHERE c = 100 and d = 'xyz' ORDER BY b 
|                 |---//創建一個集過濾、排序、覆蓋於一體的索引:(c,d,b,c1,c2)
|
|--不等於與排序  |---SELECT * FROM t WHERE c > 100 and d = 'xyz' ORDER BY b 
|               |---//(d,b)或(d,c)。至於哪種效率更高,這取決於你的數據
|               |---SELECT * FROM t WHERE c > 100 ORDER BY b
|               |---//b和c只能選一種,具體選哪一種同樣和你的數據有關
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章