平時在開發中大多在寫業務邏輯,不多關注於底層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優化知識,但願平時能學以至用吧。緩存
一.優化的策略安全
char(50)
的前20,30值惟一例:文件名
;索引緩存必定(小)時,存的索引多,消耗IO更小,能提升查找速度SELECT *
網絡傳輸速度面,弱網絡環境下,容易形成請求失效
2、其餘硬件優化服務器
Redis, Mencache
讀寫性能很是高,QPS(每秒查詢請求數)每秒達到1W以上;數據持久化用Redis,不持久化二者均可以
3、架構優化網絡
這個我聽了一下EP的分享,也看到不少種架構模型,可是仍是因爲本身經驗太少,不少仍是聽不太明白,總結一下看到過的方法吧:mysql優化
水平拆分:數據分紅多個表拆分後的每張表的表頭相同mybatis
垂直拆分:字段分紅多個表
插入數據、更新數據、刪除數據、查詢數據時:MyISAM MERGE存儲引擎,多個表合成一個表 InnoDB用alter table
,變成MyISAM存儲引擎,而後MEGRE
表更大的話就須要分庫了
主服務器寫操做的同時,同步到從服務器,保持數據完整性——主從複製
主從複製原理:基於主服務器的二進制日誌(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語句,執行。
弊端:延遲
relaylog
執行MySQL語句延遲,換成MySQL5.6
以上版本多線程,或者Tungsten
第三方並行複製工具
4、其餘
我能想到的就是:慢查詢的記錄(固然包括一些參數的設定);explain語句進行分析(分析出的結果表要詳細瞭解每一列的含義);show profile查看每個小環節的性能消耗,能夠定位到具體的一步。
寫在最後:其實平時開發過程當中仍是應該多關注一下底層實現,雖然如今的開發框架不少,許多工具都幫咱們作了底層的封裝和優化,可是咱們並不能所以喪失了這部分能力。如同咱們能夠藉助單車、汽車多樣出行,但當堵車的時候,仍是要有徒步的能力。真正理解,才能作得更完善,我真的還有很長的路要走。