正常情況下,初創公司的流量并不是很大,mysql數據庫在未做優化的情況依然可以滿足性能要求,特別是5.6版本后mysql在性能上還是有了很大提升,所以在初期并沒有花精力在此上面。但后來發生的一系列問題還是說明mysql性能優化在項目啟動時就應該重視起來。下面就出現問題的原因和需要注意的地方說明如下:

      問題來源

       開發人員之前多數使用oracle,由于oracle強大的性能和所做項目多是內部企業應用,不太可能出現性能問題。在這樣的背景下,開發人員依然按照原來的方式來寫代碼,導致后來性能問題,總結有以下幾點:

       1.sql多表聯合查詢,常常是3,4張表聯合查詢

       2.sql中使用大量函數

       3.sql中直接select *

       4.表字段缺少索引或者索引方式不對

       5.表設計考慮不周,出現大量空字段

       6.表主鍵設計成UUID,由于使用傳統機械硬盤,對尋址非常不利

       7.過多使用觸發器

       8.sql中存在復雜計算

      解決方案

       首先通過慢日志過濾出大于1s的sql語句,解決mysql性能問題,一定要利用好慢日志。然后通過執行計劃(explain)來查看sql的執行情況。具體優化措施如下:

      聯合查詢分拆成單表查詢

       如果此sql是聯合查詢,首先確認是否是可以拆分成單表查詢,然后通過程序來進行處理數據。最多不能超過兩表聯合查詢。

      建立合適索引

       通過執行計劃,對全表掃描的查詢一定要建立索引,在建立索引時,一定要考慮到此字段是否有大量空字段,字段值是否大量重復,可區分度是否高,不然建立索引的意義不大,反而是影響insert 和 delete操作。對于長字符類型的字段,增加算因時,需要增加前綴,計算方式為:select count(distinct left(b,5)) /count(distinct b) as left5,count(distinct left(b,6))/count(distinct b) as left6 from test_unique limit 1,其中5,6是預估值,對于UUID這樣長字符類型,一般前綴是6.增加索引時sql語句為:alter table test.test_unique add key (left(6));。 對于不能重復的字段,建議使用唯一索引,一是保證插入值唯一,二是提高查詢速度 。 在where、order 、group by后面的字段,盡量建立索引,通過需要注意的是如果where后面是多字段,那么需要建立聯合索引,而不是單個建立索引,并且需要注意聯合索引的順序,例如where a='x' and b = 'y',在其它sql中出現where b=‘z’這樣的情況,那么聯合索引順序為(b,a),而不是單獨建立(a,b)和(b)兩個索引,因為在建立聯合索引(b,a)時,mysql會建立兩個索引(b),(b,a)兩個索引。

      避免索引失效

       在字段上使用函數將會使索引失效,因此一定要避免在左側字段使用函數,而是提前在程序里處理好。

      盡量避免函數

       mysql提供了大量的函數,但對于這些函數,盡量不要用,而是在程序里進行處理,目前mysql對于這些函數優化工作做的并不是很好,往往有時候會導致嚴重的性能問題。

      表主鍵使用自增序列

       表主鍵盡量采用自增序列,這樣可以充分mysql的存儲特性,mysql采用B+樹存儲。需要注意的地方在于:如果是分庫分表,那么需要不能直接使用自增序列,需要采用其他方法來完成,常用的方式通過redis來維護一套ID。

除非特別注明,雞啄米文章均為原創
轉載請標明本文地址:http://www.9385095.live/software/568.html
2016年5月13日
作者:雞啄米 分類:軟件開發 瀏覽: 評論:0