[mysql-manual-5.5]7.1 優化概覽

translator: selfimpr

blog: http://blog.csdn.net/lgg201

mail: [email protected]


優化

優化是一個複雜的任務, 因爲它的目的是整個系統被優化. 雖然你可以利用對你的系統或應用的一些認知做一些局部的優化, 但如果你想要更多的優化, 你就需要了解更多的知識.

本章解釋一些優化Mysql的不同方式, 並提供示例.記住, 無論如何, 總會有其他方式讓系統變得更快, 不過要達到這個目的需要更多的努力.

優化概要

讓一個系統更快最重要的因素是它的基礎設計. 你必須知道你的系統進行了怎樣的處理, 以及它的瓶頸在哪裏. 大多數情況下, 系統的瓶頸在以下幾個方面:

  • 磁盤尋道: 磁盤查找一塊數據需要時間. 對於現代的磁盤, 這方面的平均時間消耗通常小於10ms, 因此理論上說每秒可以尋道100次. 這種情況下新的磁盤的提升已經很緩慢, 並且對單表優化非常困難. 優化尋道時間的方法就是將數據放到多個磁盤上.
  • 磁盤讀寫: 當磁盤在正確的位置時, 我們需要讀取數據. 對於現代的磁盤, 吞吐量至少在10-20MB/s. 這一點相比於尋道很容易優化, 因爲你可以從多個磁盤並行讀取.
  • CPU週期: 當我們在主存中有數據時, 我們需要處理它得到結果. 表相比於內存較小是最常見的限制因素. 但是對於小表, 速度通常不是問題.
  • 內存帶寬: 當CPU需要的數據多餘CPU緩存時, 主存的帶寬就成爲瓶頸. 這對於多數系統而言並不時常見的瓶頸, 但還是要知道它.

Mysql設計限制和折衷

當使用myisam存儲引擎時, mysql使用了非常快速的表鎖, 允許多個讀者或一個寫者. 這個存儲引擎最大的問題發生在當你有一個穩定的在同一張表上混合更新和慢的查詢操作流時. 如果某個表存在這個問題, 你可以選用其他存儲引擎.

mysql同時支持事務表和非事務表. 爲了讓非事務表可以更容易平穩的工作(發生錯誤不能回滾), mysql有下面的規則. 注意這些規則僅適用於: a) 運行在非嚴格SQL模式; b) 未INSERT或UPDATE使用了IGNORE說明符

  • 所有的列都有默認值
  • 如果你向一列插入一個超出範圍的值, mysql會將該列設置爲最合理的值而不是報告錯誤. 對於數值, 它將是0, 最小可能值或最大可能值. 對於字符串, 則是空字符串或最大能夠存入的字符串.
  • 所有的表達式都將返回一個可用的值, 而不是報告錯誤條件. 比如1/0返回NULL

要改變預定義行爲, 你可以通過設置服務端的SQL模式啓用嚴格數據處理.

爲可移植性設計應用

因爲所有的SQL服務都實現了標準SQL的不同部分, 因此編寫可移植的數據庫應用需要下一些功夫. 對於簡單的select和insert, 很容易得到可移植性, 但是當你需要更多的能力時就會變得更加複雜. 如果你希望你的應用對於多數數據庫系統都很快速, 那就更加困難了.

所有的數據庫系統都有一些弱點. 也就是說它們採用了不同的折衷設計導致了不同的行爲.

要使得複雜的應用可移植, 你需要確定它必須在哪些SQL服務器上工作, 接着確定那些服務器支持的特性. 你可以使用mysql的crash-me程序找出能用於數據庫服務器選擇的函數, 類型和限制. crash-me不會檢查每個可能的特性, 但它涵蓋的範圍仍然很廣, 執行大約450個測試. crash-me可以提供的信息的一個示例是: 如果你可能使用Informix或DB2, 就不應該使用長於18個字符的列名.

crash-me程序和mysql基準測試都是數據庫無關的. 如果看了它們的編寫實現, 你可能會有一種感覺: 你必須要讓你的應用數據庫無關. 程序可以在mysql源碼包的sql-bench目錄下找到. 他們使用perl和dbi數據庫接口編寫. 使用dbi解決了它自己的可移植性問題, 因爲dbi提供了數據庫無關的訪問.

如果你爲了數據庫無關努力, 你需要對各種數據庫服務器的瓶頸都有所瞭解. 比如, mysql在myisam表的取回和更新非常快, 但是在同一張表上混合慢的讀者和寫者時會有問題. 事務數據庫系統通常在從日誌表生成彙總表時表現不佳, 因爲這種情況下行鎖幾乎無用.

爲了讓你的應用真的數據庫無關, 你應該通過操縱你的數據定義簡單的可擴展接口. 例如, c++在多數系統上都可用, 因此可以使用基於C++的數據庫接口.

如果你使用了一些特定數據庫系統的特性(比如mysql特有的replace語句), 你應該在其他SQL服務器上編寫可選方法實現該特性. 儘管這可能比較慢, 但它至少能讓其他服務器執行相同的任務.

對於mysql, 你可以使用/* ! */語法增加mysql特有的關鍵字到語句中. /* */中的代碼被其他多數SQL服務器認爲是註釋.

如果像一些web應用一樣, 高性能比精確性還要重要, 我們就可以創建一個應用層緩存所有可以給你帶來高性能的數據. 通過讓舊的結果失效可以保持緩存的新鮮度. 這裏提供了一種處理高負載的方法, 你可以動態的增加緩存大小並設置失效時間, 直到事情恢復正常.

這種情況下, 表創建信息應該包含初始緩存大小以及表應該多長時間被刷新一次的信息.

相比於實現應用層緩存一個誘人的選擇是使用mysql的查詢緩存. 通過啓用查詢緩存, 服務端處理確定一個查詢結果集是否可以被重用的細節. 這將簡化你的應用.

mysql基準測試套件

這個基準測試套件是爲了給出某個操作在給定SQL實現上執行的是好是壞. 你可以查看mysql源代碼下的sql-bench目錄的代碼和結果, 瞭解基準測試工作.

注意: 這個基準測試是單線程的, 因此它測量了操作執行的最小時間. 我們計劃在未來爲其增加多線程測試.

要使用基準測試套件, 有以下前置條件:

  • 基準測試由mysql源代碼分發包提供, 所以需要下載源碼包.
  • 基準測試腳本使用perl以及per dbi模塊訪問數據庫服務器, 因此dbi必須安裝. 你還需要爲要測試的服務端安裝服務端特有的dbd驅動. 例如, 要測試mysql, postgresql, db2, 你必須有dbd:mysql, dbd:pg, dbd:db2模塊.

基準測試運行:

$ perl run-all-tests --server=server_name

crash-me腳本也在sql-bench目錄下. 它嘗試確認數據庫系統支持的特性, 以及它的能力和限制. 例如, 它確定:

  • 支持哪些數據類型
  • 支持多少種索引
  • 支持哪些函數
  • 可以有多大的查詢
  • varchar列有多大

使用自己的基準測試

你也應該對你的應用和數據庫做基準測試, 找出瓶頸. 在修復一個瓶頸後, 你可以着手找下一個瓶頸. 即便你的應用當前總體性能是可接受的, 你也應該至少爲每個瓶頸有個計劃並判斷如果有一天你確實需要解決時該怎樣解決.

另外還有一個免費的基準測試套件是: Open Source Database Benchmark.

系統在健康的負載下出現問題是很常見的. 我們有很多客戶是在產品碰到負載問題時聯繫我們的. 多數情況下, 性能問題是由於基礎數據庫設計(比如, 在高負載下表掃描就不好)或操作系統或類庫造成的. 大多數時候, 只要系統還沒有產品化, 這些問題都比較容易解決.

爲了避免這樣的問題, 你應該花費一些精力到最糟糕的負載下你的整個應用的基準測試上:

  • mysqlslap程序通過多個客戶端同時執行查詢模擬高負載
  • 你還可以嘗試Super Smack

上面介紹的這些工具可能會使你的系統癱瘓, 因此請確保在開發環境使用它們.


發佈了123 篇原創文章 · 獲贊 1149 · 訪問量 130萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章