淺談MySQL的優化

  平時在開發中大多在寫業務邏輯,不多關注於底層sql的執行效率,大多能交給batis的mapper作的就交給它去作。mysql

  然而這些天愈來愈發現,你們仍是很願意手寫sql的,每每一段業務邏輯,能夠用稍微複雜一些的sql直接查詢到,避免了代碼中屢次訪問數據庫(固然,我以爲若是sql太過複雜也不是很好,也許性能更好,但對於邏輯的更改和擴展都是不小的負擔,這個仍是要權衡一下),經過手寫sql,能夠提升一些查詢性能也是不錯的。linux

  今天在開發過程當中遇到了一個情景,對於多個團隊id的一個Set傳給Mysql(sql中用的in的方式)做爲查詢條件。以前僅僅用了tk-mybatis的Example的inAnd方法,後來想本身寫一下看看性能如何,因而改了mapper中的sql,使用了in標籤實現。sql

  可是在explain的時候發現,mysql竟然沒有用到in的列所創建的索引,這就讓我很迷惑了,印象中並無哪裏說到過in可使索引失效的。數據庫

  後來經過交流和測試才發現,原來是mysql底層作了優化,在他認爲in中數據量不大,使用索引並不會帶來更小開銷的狀況下,便不會使用索引。這一點其實仍是很智能的,我也想借此機會總結一下以前看到過,學習過的一些mysql優化知識,但願平時能學以至用吧。緩存

一.優化的策略安全

1. 引擎選擇(主要針對於MyISAM和InnoDB)
  • 首先是區別:
    MyISAM是非事務安全型的, 而InnoDB是事務安全型的。
    MyISAM鎖的粒度是表級, 而InnoDB支持行級鎖定。
    MyISAM支持全文類型索引, 而InnoDB不支持全文索引。
    MyISAM相對簡單, 因此在效率上要優於InnoDB, 小型應用 能夠考慮使用 MyISAM。
    MyISAM表是保存成文件的形式, 在跨平臺的數據轉移中 使用 MyISAM存儲會省去很多的麻煩。
    InnoDB表比MyISAM表更安全, 能夠在保證數據不會丟失的狀況下, 切換非事務表到事務表(alter table tablename
    type=innodb) 。
  • 而後是使用場景:
    MyISAM管理非事務表。 它提供高速存儲和檢索, 以及全文搜索能力 。 若是應用 中 須要執行大量的SELECT查詢, 那
    麼MyISAM是更好的選擇。
    InnoDB用 於事務處理應用 程序, 具備衆多特性, 包括ACID事務支持。 若是應用 中 須要執行大量的INSERT或UPDATE操
    做, 則應該使用 InnoDB, 這樣能夠提升多用 戶併發操做的性能。
2. 正確使用索引
  • 適合創建的:where子句,鏈接子句,order by,group by, distinct 後,不要再select列加。
  • 若是數據不多更新,而且查詢字段很少,能夠考慮索引覆蓋。
  • 索引值應該不相同,惟一值時效果最好,大量重複效果不好
  • 使用短索引,指定前綴長度char(50)的前20,30值惟一例:文件名;索引緩存必定(小)時,存的索引多,消耗IO更小,能提升查找速度
  • 最左前綴n列索引,最左列的值匹配,更快。
  • like查詢,索引會失效,儘可能少用like;or,計算操做,函數,數據類型轉換等都會使索引失效。
  • 多用簡單句,避免臨時表過多。
  • 能用union all就不用union(union會多排序和去重的花銷)
  • 索引自己佔空間,而且維護代價高,不是越多越好。
3. 避免使用SELECT *
  • 返回結果過多,下降查詢的速度
  • 過多的返回結果,會增大服務器返回給端的數據傳輸量。例:網絡傳輸速度面,弱網絡環境下,容易形成請求失效

2、其餘硬件優化服務器

1. Linux內核用內存開緩存存放數據
  • 寫文件:文件延遲寫入機制,先把文件存放到緩存,達到必定程度寫進硬盤
  • 讀文件:同時讀文件到緩存,下次須要相同文件直接從緩存中取,而不是從硬盤取
2. 增長應用緩存
  • 本地緩存:數據防盜服務器內存的文件中
  • 分佈式緩存:Redis, Mencache 讀寫性能很是高,QPS(每秒查詢請求數)每秒達到1W以上;數據持久化用Redis,不持久化二者均可以 

 

3、架構優化網絡

 這個我聽了一下EP的分享,也看到不少種架構模型,可是仍是因爲本身經驗太少,不少仍是聽不太明白,總結一下看到過的方法吧:mysql優化

1. 分表
  • 水平拆分:數據分紅多個表拆分後的每張表的表頭相同mybatis

  • 垂直拆分:字段分紅多個表

  • 插入數據、更新數據、刪除數據、查詢數據時:MyISAM MERGE存儲引擎,多個表合成一個表 InnoDB用alter table,變成MyISAM存儲引擎,而後MEGRE

  • 表更大的話就須要分庫了

2. 讀寫分離
  • 讀是一些機器,寫是一些機器,二進制文件的主從複製,延遲解決方案。
  • 數據庫壓力大了,能夠把讀和寫拆開,對應主從服務器,主服務器寫操做、從服務器是讀操做。
  • 主服務器寫操做的同時,同步到從服務器,保持數據完整性——主從複製

  • 主從複製原理:基於主服務器的二進制日誌(binlog)跟蹤全部的對數據庫的完整更改實現。要實現主從複製,必須在主服務器上啓動二進制日誌,主從複製是異步複製,三個線程參與:主服務器一個線程(IO線程)、從服務器兩個(IO線程和SQL線程)

  • 主從複製過程:

  • a. 從數據庫,執行start slave開啓主從複製;

  • b. 從數據庫IO線程會經過主數據庫受權的用戶請求鏈接主數據庫,並請求主數據庫的binlog日誌的指定位置,change master命令指定日誌文件位置

  • c. 主數據庫收到IO請求,負責複製的IO線程跟據請求讀取的指定binlog文件返回給從數據庫的IO線程,返回的信息除了日誌文件,還有本次返回的日誌內容在binlog文件名稱和位置

  • d. 從數據庫獲取的內容和位置(binlog),寫入到(從數據庫)relaylog中繼日誌的最末端,並將新的binlog文件名和位置記錄到master-info文件,方便下次讀取主數據庫的binlog日誌,指定位置,方便定位

  • e. 從數據庫SQL線程,實時檢測本地relaylog新增內容,解析爲SQL語句,執行。

  • 弊端:延遲

  • 主從複製延遲解決方案:
  • a. 定位問題:延遲瓶頸,IO壓力大,升級硬件,換成SSD
  • b. 單線程從relaylog執行MySQL語句延遲,換成MySQL5.6以上版本多線程,或者Tungsten第三方並行複製工具
  • c. 都不行,直接分庫
3. 分庫
  • 這一部分網上的資料也不少,可是因爲本身確實經驗缺少,先不作整理了。(如今以爲,複製卻不能消化的是沒有意義的)

 

4、其餘

  我能想到的就是:慢查詢的記錄(固然包括一些參數的設定);explain語句進行分析(分析出的結果表要詳細瞭解每一列的含義);show profile查看每個小環節的性能消耗,能夠定位到具體的一步。

 

寫在最後:其實平時開發過程當中仍是應該多關注一下底層實現,雖然如今的開發框架不少,許多工具都幫咱們作了底層的封裝和優化,可是咱們並不能所以喪失了這部分能力。如同咱們能夠藉助單車、汽車多樣出行,但當堵車的時候,仍是要有徒步的能力。真正理解,才能作得更完善,我真的還有很長的路要走。

相關文章
相關標籤/搜索