一、若是咱們定義了主鍵(PRIMARY KEY),那麼InnoDB會選擇主鍵做爲彙集索引。
若是沒有顯式定義主鍵,則InnoDB會選擇第一個不包含有NULL值的惟一索引做爲主鍵索引。
若是也沒有這樣的惟一索引,則InnoDB會選擇內置6字節長的ROWID做爲隱含的彙集索引(ROWID隨着行記錄的寫入而主鍵遞增,這個ROWID不像ORACLE的ROWID那樣可引用,是隱含的)。
二、若是表使用自增主鍵,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置(主鍵插入性能最高,由於是順序的),當一頁寫滿,就會自動開闢一個新的頁
三、若是使用非自增主鍵(若是身份證號或學號等),因爲每次插入主鍵的值近似於隨機,所以每次新紀錄都要被插到現有索引頁得中間某個位置
此時MySQL不得不爲了將新記錄插到合適位置而移動數據,甚至目標頁面可能已經被回寫到磁盤上而從緩存中清掉,此時又要從磁盤上讀回來,這增長了不少開銷,同時頻繁的移動、分頁操做形成了大量的碎片,獲得了不夠緊湊的索引結構,後續不得不經過OPTIMIZE TABLE來重建表並優化填充頁面。
mysql
一、添加索引的字段的值,是存放在索引構建的b+tree的葉子節點上,並通過排序存放;
二、若有相關查詢進來,會經過索引建立的b+tree獲取數據所在的數據頁(b+tree與二分查找法配合,只需幾回io消耗就能夠找到對應的數據頁);
三、找到數據頁後,將頁加載到buffer pool中,再內存中從數據頁中獲取具體數據;
算法
B+樹是一個平衡的多叉樹結構,從根節點到每一個葉子節點的高度差值不超過1,並且同層級的節點間有指針相互連接,是有序的,以下圖:sql
哈希索引就是採用必定的哈希算法,把鍵值換算成新的哈希值,檢索時不須要相似B+樹那樣從根節點到葉子節點逐級查找,只需一次哈希算法便可,是無序的,以下圖所示:
數據庫
等值查詢,哈希索引具備絕對優點(前提是:沒有大量重複鍵值,若是大量重複鍵值時,哈希索引的效率很低,由於存在所謂的哈希碰撞問題。);MySQL中在緩衝池中會開啓自適應哈希索引。
緩存
一、彙集索引的選擇:
會優先選擇顯示建立的主鍵做爲彙集索引;
若是沒有則選擇第一個建立的非空惟一索引做爲彙集索引;
如都沒有則系統會建立一個實例級別的rowid做爲彙集索引。
二、彙集索引的特色:
彙集索引的鍵值順序決定了表數據行的物理順序;
葉子節點上存放的是整行數據;
一張表只能建立一個彙集索引。
架構
如一個普通索引的插入操做,對於非彙集索引葉子節點的插入再也不是順序的了,這時就須要離散地訪問非彙集索引頁,因爲隨機讀取的存在而致使了插入操做性能降低。
MySQL經過insert buffer(插入緩衝)這個特性,來優化普通索引的寫入操做。
對於非彙集索引的插入操做,不是每一次直接插入到索引頁中,而是先判斷插入的非彙集索引頁是否在緩衝池中,若在,則直接插入;若不在,則先放入到一個Insert Buffer對象中。而後再以必定的頻率和狀況進行Insert Buffer和輔助索引頁子節點的merge(合併)操做,這時一般能將多個插入合併到一個操做中(由於在一個索引頁中),這就大大提升了對於非彙集索引插入的性能。
併發
建前綴索引時,最重要的是定義好長度,把握好度,便可節省內存使用,又能夠減小額外的查詢成本;前綴索引會對覆蓋索引產生影響
ide
索引關乎着MySQL性能,影響着方方面面;
最主要的有這幾點:提高讀性能;減小鎖等待和死鎖;主從複製中sql線程利用索引進行回放,減小主從延遲。
函數
首先你們要知道索引的用處:索引就是用來從大量數據中獲取少部分數據
一、常常更新的字段
二、重複值比較高的字段
三、不常常查詢的字段
四、若是表中記錄數特別特別少,就不建議在表中字段上建立索引;可是若是達到萬級別以上,仍是建議建立索引
性能
利用用戶ip精確匹配的特色;假如原先用戶ergou@'192.168.58.%',從新建立一個用戶,如ergou@'192.168.58.51',並從新設置密碼;這樣就會用戶經過用戶ergou登陸,就會匹配到ergou@'192.168.58.51'。
一、delete是邏輯刪除,按行刪除數據,效率低,支持回滾;可是你們要知道delete只是作了一個刪除的標記,具體的刪除是由purge線程完成刪除,這纔會釋放空間
2.truncate是物理刪除,釋放空間,速度快,不支持回滾
一、從性能來講,空值會存放在b+tree的左邊,形成索引性能降低
二、空值須要更多的存儲空間,多1個字節(null列上創建索引後)
三、形成統計結果的不許確,count(*)會統計容許爲null的字段,count(某字段)不含null值
一、where條件:
列進行計算:
explain select * from orders where o_custkey=o_custkey+1;
列使用函數:
explain select * from orders where o_custkey=ceil(o_custkey);
列進行隱式轉換:
explain select * from emp where ename=007;
二、聯合索引:用到範圍查詢,只能用到部分索引
三、聯表查詢:
關聯條件字符集不一樣,不走索引
關聯條件的列類型不一樣,不走索引
四、其餘狀況:
。select * from emp;
。查詢結果集大於數據量的30%,不走索引
explain select * from emp where empno > 7000;
。索引自己失效
。like '%s'
explain select * from emp where ename like '%s';
。not in(111,9999) 普通索引,若是是主鍵索引,會被優化爲範圍查詢,能夠利用索引
explain select * from emp where empno not in(111, 9999);
。!=
explain select * from emp where empno != 9999;
讀未提交(read-uncommitted)RU,產生髒讀
讀已提交(read-committed)RC,不會產生髒讀,產生不可重複讀;
可重複讀(repeatable-read)RR,不會產生髒讀,不會產生不可重複讀;會產生幻讀(可是innodb默認會阻止產生幻讀,經過鎖實現);
可串行化(serializeable),不會產生髒讀,不會產生不可重複讀;不會產生幻讀;完美符合事務,但性能最低
MySQL InnoDB存儲引擎,實現的是基於多版本的併發控制協議——MVCC (Multi-Version Concurrency Control)
MVCC最大的好處:讀不加鎖,讀寫不衝突。在讀多寫少的OLTP應用中,讀寫不衝突是很是重要的,極大的增長了系統的併發性能,現階段幾乎全部的RDBMS,都支持了MVCC。
MVCC由數據頁中的事務id、回滾指針+undo日誌,read view構成
階段1:寫redo log,事務處於prepare
階段2:寫binlog,事務處於commit
寫binlog成功有xid事件,會將xid寫入redo log
①redo log是innodb存儲引擎獨有的,binlog是不區分存儲引擎 ②記錄內容不一樣,redo log是物理邏輯日誌,記錄頁的變化過程;binlog是邏輯日誌,記錄事務具體操做的內容 ③寫入時間不一樣,先寫入redo log,再寫入binlog ④redo log是循環使用文件,binlog每次新增一個文件 二10、如何快速將一張大表遷移到其餘數據庫實例 二11、事務是如何實現的 二12、MySQL在RR隔離級別下如何阻止幻讀 二十3、生產如何儘可能避免死鎖 二十4、不一樣隔離級別下、不一樣索引下innodb行鎖的粒度是什麼樣的 二十5、mysqldump備份原理 二十6、innodb存儲引擎行鎖衝突問題 二十7、MySQL在備份時,怎麼作到一致性備份 二十8、主從複製原理 二十9、主從複製架構的瓶頸 三10、如何減小主從複製延遲 三11、過濾複製會產生哪些問題 三12、主從複製中斷如何處理 三十3、1062或者1032錯誤,如何解決 三十4、如何將數據庫回檔到任意的一天 三十5、說說5.7和8.0在主從複製方面的改進 三十6、DML變慢的緣由