數據庫性能優化(MySQL)

序:mysql

    即便有較長的緩存有效期和較理想的緩存命中率,可是緩存的建立和緩存過時後的重建都是須要訪問數據庫的。對數據庫寫操做不是很容易引入緩存策略。web

11.1 查看數據庫狀態sql

    能夠經過show status、show innodb status 來查看MySQL數據庫的狀態,使用mysqlreport這個第三方工具可以使數據庫狀態報告更好看(mysqlreport本質是經過MySQL內部命令和工具來統計狀態的)。數據庫

11.2 正確使用索引緩存

    在影響數據庫查詢性能的衆多因素中,索引絕對是一個重量級的因素,若是索引使用不當,則數據庫的其它優化可能無濟於事。數據結構

    索引是用於快速定位到表記錄所在地址的一種數據結構(BTree、Hash、RTree等)。經過索引去查找記錄即爲索引掃描。多線程

    索引掃描不必定比全表掃描性能更好,要看狀況。查詢優化器會爲一次查詢是否使用索引以及決定使用哪一個索引,固然,有時查詢優化器也會犯錯誤。併發

    數據庫的索引須要定位到每行記錄,全部索引項的數量也會很是多,經過索引列表查找某索引項也會存在必定的小開銷。異步

    除了普通索引外還有惟一索引、主鍵索引、非空索引、全文索引等,不一樣的索引只是約束和用途不同。像惟一索引在插入數據時就會增長必定的開銷,由於它每插入一次都要判斷是否重複。分佈式

    通常若是一個字段出如今查詢語句基於行的選擇、分組和排序,那麼爲該字段創建索引多是有價值的。

    explain只可分析查詢語句,不能用於分析更新操做的語句。

    在explain中,若type爲const,說明查詢能夠經過索引直接找到匹配行,key爲PRIMARY說明使用了主鍵索引。若type爲all,說明使用了全表掃描,索引未使用上,此時的key 爲空。若type爲ref,說明查詢的結果可能有多個匹配行。若type爲index,說明查詢只須要在索引中掃描便可。

    一次查詢對一個數據表只能使用一個索引,不能進行索引效應疊加。

    最左前綴是使用組合索引的最基本原則。

    非順序的索引類型如hash對order by是無效的。

    對於包含group by的查詢,數據庫通常是先將記錄分組後放到臨時表中,而後對其進行函數運算。這時如有恰當索引時,可以使用索引來代替臨時表的使用。

    可使用慢查詢配置來記錄查詢慢的語句,也能夠記錄未使用索引的查詢語句。

    爲了節省查找索引的時間,能夠將索引緩存起來放到內存中,這樣最理想的狀況,索引能夠直接在內存中查找而不須要訪問磁盤。MyISAM表包括3個文件,分別是.frm、.MYI、.MYD。也即MyISAM表類型只緩存索引不緩存數據文件。因爲存在索引寫緩存機制,MyISAM表類型對於索引的寫操做存在延遲。

    在使用索引時也要考慮到其代價,索引會佔據更多的磁盤空間,有時甚至比數據文件還要大。當在創建了索引的字段上進行更新時,其索引也須要更新,這個開銷可不小。索引也須要花時間來維護。

11.3 鎖定與等待

    鎖機制是影響查詢性能的另外一個因素,當多個併發用戶同時訪問同一資源時,數據庫爲保證併發訪問的一致性,使用數據庫鎖來協調訪問。

    查詢時間的開銷包括查詢自己的計算時間和查詢前的等待時間,索引影響的是前者,鎖機制影響的是後者。

    MySQL爲MyISAM表類型提供的是表鎖。表鎖容許多個線程同時讀取數據(select),但對於更新操做會排斥全部其它的查詢包括select,並且更新操做具備默認的高優先級。

    若是大部分爲查詢操做,只有少量更新操做,則不會存在太多的鎖等待。

    MySQL爲InnoDB表類型提供的是行鎖。行鎖能夠帶來update和select不一樣線程對不一樣的行記錄能夠併發地進行。

    行鎖並不必定比表鎖快,開銷不必定比表鎖小,尤爲是涉及全表掃描時行鎖的開銷更大。

11.4 事務性表的性能

    InnoDB除了支持行鎖外,它還支持事務,InnoDB實現事務的方法是經過預寫日誌的方式。當有事務提交時,InnoDB將它寫入到內存的事務日誌緩衝區中,隨後將事務日誌寫入磁盤,從而更新實際的數據和索引。

    事務日誌寫入磁盤的時機:

    innodb_flush_log_at_trx_commit=1時,表明事務提交時事務日誌當即寫入磁盤,同時更新數據和索引。

    innodb_flush_log_at_trx_commit=0時,表明事務提交時事務日誌不當即寫入磁盤,而是每隔1秒寫入磁盤文件一次,並刷新到磁盤同時更新數據和索引。

    innodb_flush_log_at_trx_commit=2時,表明事務提交時事務日誌當即寫入磁盤文件,每隔1秒刷新到磁盤同時更新數據和索引。

    經過以上3種時機能夠對比出它們的可靠性和性能。

11.5 使用查詢緩存

    查詢緩存就是將select查詢結果放在內存中,key是select語句,value是該查詢語句的結果。不管是MyISAM仍是InnoDB引擎,查詢緩存均可以很好地工做,起到提高性能的做用。查詢緩存要注意緩存過時策略,在MySQL中,若一個表中有更新操做,則該表的全部查詢緩存將失效。所以,對於select密集型更新不多的應用很適合使用查詢緩存。

11.6 臨時表

    在explain查詢語句時,有時能夠看到Using temporary狀態,這說明查詢過程使用了臨時表來存儲中間數據,能夠經過合理使用索引來避免建立臨時表狀況。若臨時表的使用不可避免,那麼也應該儘可能減小臨時表自己的開銷。

    MySQL的臨時表能夠建立在磁盤、內存和臨時文件中。固然,建立在磁盤上的開銷最大。有時在使用show processlist能夠看到查詢狀態中有Coping to tmp table on disk,這說明MySQL在將臨時表從內存中複製到磁盤上以節省內存空間。

    能夠經過tmp_table_size選項來設置用於存儲臨時表的內存空間大小。一旦空間不夠用纔會使用磁盤來存儲。

11.7 線程池

    MySQL使用多線程來處理併發鏈接。爲減小重複線程的建立能夠儘可能使用持久鏈接或將鏈接緩存起來(經過在my.cnf中配置thread_table_size=個數來設置)。

11.8 反範式設計

    所謂範式就是對關係數據庫中的關係的要求或約束,有不一樣程序的要求就有不一樣的範式。一般遵循到3NF便可,3NF就是非主鍵字段之間不能存在依賴關係,這樣能夠避免刪除、更新、插入異常,保持關係的一致性,減小數據冗餘。

    反範式化就是違背關係設計的要求或約束,用於減小讀取數據的開銷,增長必定的數據冗餘,但這樣同時也增長了寫數據的開銷,由於要保持冗餘數據的一致性。固然,爲了保證數據庫寫性能能夠異步寫數據。若不想反範式則可使用非關係型數據庫。

11.9 使用非關係數據庫

    key-value數據庫使用半結構化存儲數據,全部數據只有一個索引即key,能夠將反範式化引起的數據副本保存到key-value數據庫中,這樣比關係數據庫具備更出色的併發性能。

    MemcacheDB在性能方面比較出色,是一個分佈式的key-value數據庫,使用Memcache協議,這意味着使用了Memcache的web應用能夠不進行任何的修改而遷移到MemcacheDB上。

    不是全部的應用都適合用key-value數據庫,該用關係查詢的時候仍是得用關係數據庫,key-value數據庫只是爲避免反範式化引起的寫數據開銷方案之一。固然,MemcacheDB封裝了Berkeley DB的複製功能,能夠經過主從複製來擴展MemcacheDB的規模,提高可用性。

相關文章
相關標籤/搜索