MySQL(二) MySql常用優化

湖人總冠軍發表於2018-03-25
在上一篇部落格中簡單的介紹了下MySql的索引,在本篇部落格中將進一步介紹MySql的索引以及常用的Mysql優化。

一、常見的樹結構: 

  • 二叉樹:每個父節點大於左孩子節點,小於右孩子節點 。
  • 平衡二叉樹:二叉樹的基礎上,每個節點的子樹高度差不大於1 。
  • BTree:是一種平衡多路搜尋樹,另外並保證了每個葉子結點到根節點的距離相同,每個節點儲存了dataMySQL(二) MySql常用優化
  • B+Tree:非葉子結點只存放key,葉子節點儲存key,data.葉子節點可以包含一個指標指向另一個葉子節點以加速順序存取。MySQL(二) MySql常用優化

二、MySql儲存引擎 

  • InnoDB儲存引擎 當前MySQL儲存引擎中的主流,InnoDB儲存引擎支援事務、支援行鎖、支援非鎖定讀、支援外來鍵。 
  • MyISAM儲存引擎 MyISAM不支援事務,不支援行級鎖,支援表鎖(效率低),支援全文索引,最大的缺陷是崩潰後無法安全恢復。

在InnoDB和MyISAM中索引都採用了B+Tree結構,但是實現方式並不相同:

  1. 在MyISAM中葉子節點的data域並不存放資料而是存放資料記錄的地址,所以MyISAM中索引檢索的演算法為首先按照B+Tree搜尋演算法搜尋索引,如果指定的Key存在,則取出其data域的值,然後以data域的值為地址,讀取相應資料記錄。
  2. 在InnoDB中有聚集索引和非聚集索引(輔助索引):
    • 聚集索引:非葉子結點存放的是<key,point>,point就是指向下一層的指標。 葉子結點儲存了這一行的資訊,因此通過主鍵索引可以快速獲取資料。InnoDB中通常主鍵就是一個聚集索引。準確來說聚集索引並不是某種單獨的索引型別,而是一種資料儲存方式。就是指在同一個結構中儲存了B+tree索引以及資料行。 innoDB中,使用者如果沒有設定主鍵索引,會隨機選擇一個唯一的非空索引替代, 如果沒有這樣的索引,會隱式的定義一個主鍵作為隱式的聚集索引。
    • 非聚集索引:非聚集索引的葉子結點並沒有存放資料,而是儲存相應行資料的聚集索引鍵,即主鍵。當通過非聚集助索引來查詢資料時,InnoDB儲存引擎會遍歷非聚集索引找到主鍵,然後再通過主鍵在聚集索引中找到完整的行記錄資料。

三、總結

使用B+Tree作為索引結構的原因:

    • B-Tree每個節點中不僅包含資料的key值,還有data值。而每一個頁的儲存空間是有限的,如果data資料較大時將會導致每個節點(即一個頁)能儲存的key的數量很小,當儲存的資料量很大時同樣會導致B-Tree的深度較大,增大查詢時的磁碟I/O次數,進而影響查詢效率。在B+Tree中,所有資料記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只儲存key值資訊,這樣可以大大加大每個節點儲存的key值數量,降低B+Tree的高度。

    四、MySql常用優化

    1. 索引失效的情況
    • 以%開頭的like查詢
    • (not , not in, not like, <>, != ,!>,!<)不會使用索引
    • 如果條件中有or,即使其中有部分條件帶索引也不會使用
    • where 子句裡對索引列上有數學運算或者使用函式,用不上索引
    • 索引列的資料型別存在隱形轉換則用不上索引。比如字串,那一定要在條件中將資料使用引號引用起來
  1. sql優化 
    • 分解關聯查詢:將關聯(join)放在應用中處理,執行簡單的sql,好處是:分解後的sql通常由於簡單固定,能更好的使用mysql快取。還可以可以減少鎖的競爭。
    • SELECT子句中避免使用*號 ,它要通過查詢資料字典完成的,意味著將耗費更多的時間,而且SQL語句也不夠直觀。
    • 關於Limit 在使用Limit 2000,10這種操作的時候,mysql會掃描偏移量(2000條無效查詢)資料,而只取後10條,儘量想辦法規避。
    • 通常情況下,使用一個效能好的sql代替使用多個sql。除非這個sql過長效率低下或者對於delete這種語句,過長的delete會導致太多的資料被鎖定,耗盡資源,阻塞其他sql。 
    • WHERE子句中的連線順序 資料庫採用自右而左的順序解析WHERE子句,所以那些可以過濾掉最大數量記錄的條件最好寫在WHERE子句的最右。 
    • 選擇最有效率的表名順序 資料庫的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表將被最先處理 在FROM子句中包含多個表的情況下: 如果是完全無關係的話,將記錄和列名最少的表寫在最後。如果是有關係的話,將引用最多的表,放在最後。
    • 刪除全表資料用TRUNCATE替代DELETE 這裡僅僅是:DELETE是一條一條記錄的刪除,而Truncate是將整個表刪除,保留表結構,這樣比DELETE快
    •  多使用內部函式提高SQL效率 
    • 使用表或列的別名,使用簡短的別名也能稍微提高一些SQL的效能。畢竟要掃描的字元長度變少了 
    • 用 >= 替代 > ,低效:> 3首先定位到=3的記錄並且掃描到第一個大於3的記錄。高效:>= 4 直接跳到第一個等於4的記錄 
    • 用IN替代OR 
  2. 資料庫結構優化
    • 表結構優化:欄位儘量使用非空約束,因為在MySql中含有空值的列很難進行查詢優化,NUll值會使索引以及索引的統計資訊變得很複雜 
    • 數值型別的比較比字串型別的比較效率要高得多, 
    • 儘量使用TIMESTAMP而非DATETIME(查詢效率)
    • 單表不要有太多的欄位,建議在20以內 
    • 合理加入冗餘欄位
    • 垂直表拆分 水平表拆分 





    參考博文:blog.csdn.net/u013235478/…


    相關文章