MySQL使用與優化總結

存儲引擎的選擇:MyISAM vs InnoDB

MyISAM:支持全文索引;使用表級鎖;讀併發性能好。

	InnoDB:支持事務和外鍵;使用行級鎖;寫併發性能較好。

在實際應用場景中,咱們通常都使用InnoDB做爲默認的存儲引擎,除了支持事務和行鎖是比較重要的兩個緣由外,其實MyISAM在實際應用場景中意義也不大,看看下面幾個緣由:前端

  • 全文索引徹底能夠(也應該)用第三方軟件來替代,好比:Sphinx;mysql

  • 讀性能高的特色徹底能夠用前端緩存來替代,這已是互聯網應用的標配了;sql

  • 表級鎖在併發寫操做多時會嚴重影響讀操做(寫優先);數據庫

使用與優化

DB的優化

  • 創建合適的索引:緩存

    儘可能讓全部查詢都走索引,這個效果是很明顯的。安全

  • 表空間優化:併發

    在刪除或更新比較頻繁的表上,若是包含varchar,text之類的字段,須要按期地執行表空間優化,optimaize table xxx,整理磁盤碎片,回收表數據和索引數據佔用的空閒空間;函數

  • 配置參數優化:工具

    innodb_buffer_pool_size  innodb表數據和索引數據的內存緩衝大小,很關鍵,能夠有效減小磁盤IO。
      innodb_flush_log_at_trx_commit 決定事務日誌怎麼記錄,這個對性能提高也很關鍵,在線下批量寫數據時能夠考慮設置爲0.或者寫操做頻繁但容許故障時丟失極少許數據的狀況也能夠考慮。
      query_cache 這個參數有些微妙,由於query cache在數據表中有任何數據修改時就會失效,對於寫操做頻繁的表來講,有可能還會下降性能。對於讀操做爲主的表來講,效果仍是很明顯的,可是一般場景下咱們都依賴於前端緩存,因此對於這個參數的設置來講,還要看具體業務場景。
      max_connections 控制併發鏈接數,不能太大,不然後果很嚴重。
  • 拆分與擴容:性能

    庫拆分:通常是把同一實例上的數據庫分到多個實例上來分擔壓力(這種比較簡單,作一份複製,應用端改個ip就行),或者是把一個庫裏面的部分表單獨放到另外一個實例庫中(這種比較麻煩,須要應用端配合修改程序)。
      表拆分:也分兩種,一種是把一些字段的拆出到新表裏,好比按業務分,或者是像text之類的大字段拆分。另外一種是表記錄數太大,超出了單表承受能力,須要水平擴展到多張表。表拆分比較麻煩,都須要應用端配合修改程序。

SQL的優化

  • 儘可能用上索引,能用主鍵查詢最好了
  • 儘可能縮小掃描範圍,經典場景就是limit分頁偏移量的優化,其實在實際業務場景下頗有不少相似的場景,咱們徹底能夠按id號或者時間限制來顯著縮小查詢掃描範圍
  • 儘可能減小錶鏈接查詢,最好是單表查詢(錶鏈接可能用上臨時表,對DB消耗很大;而單表查詢能夠快速返回,把計算操做放到前端應用去作,減小DB壓力)。若是前端併發沒有控制好的話,性能較差的錶鏈接查詢可能會拖死DB
  • 儘可能作等值查詢,不等條件查詢和逆向查詢不走索引
  • 用union替代or、in操做
  • 不作前置模糊查詢,不走索引
  • 排序和分組操做盡可能在應用端作,減小DB的CPU壓力
  • 在查詢列上不做函數運算:select concat('foo','bar') as str from xxx;

應用的優化

  • 儘可能不在DB端作運算,能在應用端作的事就不依賴DB
  • text/blob之類的數據儘可能不在DB中存儲,能夠採用其它key/value型的存儲
  • 大sql拆分紅小sql查,不作錶鏈接
  • 用好鏈接池,減小鏈接開銷(這裏要注意鏈接池的空閒時間與數據庫空閒時間的配置)
  • 有冷熱數據的場景,儘可能均攤壓力
  • 考慮讀寫分離(這裏要注意slave的延時,master寫頻繁的狀況下,slave延時也是另人很頭疼的,對數據一致性敏感的應用場景是有隱患的)
  • 最後提一下,preparedstatement,最大的做用是防止SQL注入。預編譯功能也能夠嘗試使用,可是要開啓前端sql緩存纔好,這個仍是看具體應用場景吧,大多數互聯網應用還沒到靠這個功能來提高性能的狀況。

簡單故障排查技巧

慢查詢排查

  • 日誌查看:slow.log,這個是mysql配置文件裏設置的,要開啓。

  • 實時查看:select * from information_schema.processlist where time > 2;

    處理方式:

    • 慢查詢日誌分析工具:mysqlsla,mysqldumpslow等,對症下藥進行SQL優化;
    • 實時的慢查詢若是影響了應用的響應,能夠直接kill掉查詢線程。執行kill [thread_id]便可。

Lock狀況排查

肯定數據庫有鎖住狀況看兩個地方,在processlist中能夠看到state那一列有lock相關的狀態,這裏只能看到一個狀態,最主要是經過下面這個命令來查看show innodb engine status,這裏會顯示詳細的鎖和事務發生的信息。至於怎麼解決,要看應用端怎麼來控制了。

Slave延時排查

在slave實例上執行show slave status查看slave的狀態,主要關注如下三個:

Slave_IO_Running: Yes // 負責讀取binlog的線程是否正常運行
Slave_SQL_Running: Yes // 負責在slave上執行sql的線程是否正常運行
Seconds_Behind_Master: 0 // slave比master延時多長時間,單位:秒

若是出現IO和SQL線程狀態爲No的狀況,那說明slave同步已經中止了,能夠經過Last_Error這個看到最近的錯誤。若是要恢復slave,通常兩種操做:一是重作slave,保證數據更準確;一種是跳過出錯的sql,stop slave;set global sql_slave_skip_counter=1;start slave;,這是跳過一條sql,也可跳過多條,這種方式可能致使slave數據不一致。

監控

內置命令

status
show global status
show variables

外部監控

第三方的監控工具,能夠提供圖形化的界面。cacti,ganglia等開源軟件都提供了監控mysql的插件。

簡單說說mysql高可用

兩種方式:

方式一:使用MySQL Cluster:讀擴展性好,寫性能會有必定降低。不是很成熟,線上慎用。

方式二:Master + Slave配合虛擬IP + LVS + keepalived實現簡單的高可用,這種方案的隱患就是:虛擬ip切換間隙會有短暫不可用;slave提高到master會有失敗的狀況;

最後

數據庫通常都存儲了應用的關鍵數據,能夠說是一個公司產品的生命,因此數據的安全也很是重要,要作好權限控制(嚴格控制權限,儘可能防止誤操做形成數據丟失),及時備份數據(異地,多機房),對於核心敏感數據還要作好保密工做。

推薦閱讀:

Memcached應用總結

相關文章
相關標籤/搜索