MySQL(二) MySql經常使用優化

在上一篇博客中簡單的介紹了下MySql的索引,在本篇博客中將進一步介紹MySql的索引以及經常使用的Mysql優化。

1、常見的樹結構: 

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

2、MySql存儲引擎 

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

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

  1. 在MyISAM中葉子節點的data域並不存放數據而是存放數據記錄的地址,因此MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,則取出其data域的值,而後以data域的值爲地址,讀取相應數據記錄。
  2. 在InnoDB中有彙集索引和非彙集索引(輔助索引):
    • 彙集索引:非葉子結點存放的是<key,point>,point就是指向下一層的指針。 葉子結點保存了這一行的信息,所以經過主鍵索引能夠快速獲取數據。InnoDB中一般主鍵就是一個彙集索引。準確來講彙集索引並非某種單獨的索引類型,而是一種數據存儲方式。就是指在同一個結構中保存了B+tree索引以及數據行。 innoDB中,用戶若是沒有設置主鍵索引,會隨機選擇一個惟一的非空索引替代, 若是沒有這樣的索引,會隱式的定義一個主鍵做爲隱式的彙集索引。
    • 非彙集索引:非彙集索引的葉子結點並無存放數據,而是存儲相應行數據的彙集索引鍵,即主鍵。當經過非彙集助索引來查詢數據時,InnoDB存儲引擎會遍歷非彙集索引找到主鍵,而後再經過主鍵在彙集索引中找到完整的行記錄數據。

3、總結

使用B+Tree做爲索引結構的緣由:算法

    • B-Tree每一個節點中不只包含數據的key值,還有data值。而每個頁的存儲空間是有限的,若是data數據較大時將會致使每一個節點(即一個頁)能存儲的key的數量很小,當存儲的數據量很大時一樣會致使B-Tree的深度較大,增大查詢時的磁盤I/O次數,進而影響查詢效率。在B+Tree中,全部數據記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只存儲key值信息,這樣能夠大大加大每一個節點存儲的key值數量,下降B+Tree的高度。

4、MySql經常使用優化

  1. 索引失效的狀況
    • 以%開頭的like查詢
    • (not , not in, not like, <>, != ,!>,!<)不會使用索引
    • 若是條件中有or,即便其中有部分條件帶索引也不會使用
    • where 子句裏對索引列上有數學運算或者使用函數,用不上索引
    • 索引列的數據類型存在隱形轉換則用不上索引。好比字符串,那必定要在條件中將數據使用引號引用起來
  2. 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 
  3. 數據庫結構優化
    • 表結構優化:字段儘可能使用非空約束,由於在MySql中含有空值的列很難進行查詢優化,NUll值會使索引以及索引的統計信息變得很複雜 
    • 數值類型的比較比字符串類型的比較效率要高得多, 
    • 儘可能使用TIMESTAMP而非DATETIME(查詢效率)
    • 單表不要有太多的字段,建議在20之內 
    • 合理加入冗餘字段
    • 垂直表拆分 水平表拆分 





參考博文: blog.csdn.net/u013235478/…
相關文章
相關標籤/搜索