數據庫優化是一項很復雜的工作,因為這最終需要對系統優化的很好理解才行。盡管對系統或應用系統的了解不多的情況下優化效果還不錯,但是如果想優化的效果更好,那麼就需要對它了解更多才行。
本章主要講解了幾種優化MySQL的方法,並且給出了例子。記著,總有各種辦法能讓系統運行的更快,當然了,這需要更多的努力。
1.優化概述
讓系統運行得快得最重要因素是數據庫基本的設計。並且還必須清楚您的系統要用來做什麼,以及存在的瓶頸。
最常見的系統瓶頸有以下幾種:
磁盤搜索。它慢慢地在磁盤中搜索數據塊。對現代磁盤來說,平時的搜索時間基本上小於10毫秒,因此理論上每秒鐘可以做100次磁盤搜索。這個時間對於全新的新磁盤來說提高的不多,並且對於只有一個表的情況也是如此。加快搜索時間的方法是將數據分開存放到多個磁盤中。
磁盤讀/寫。當磁盤在正確的位置上時,就需要讀取數據。對現代磁盤來說,磁盤吞吐量至少是10-20MB/秒。這比磁盤搜索的優化更容易,因為可以從多個媒介中並行地讀取數據。
CPU周期。數據存儲在主內存中(或者它已經在主內存中了),這就需要處理這些數據以得到想要的結果。存在多個?硐啾饒诖嫒萘坷此蹈?竅拗頻囊蛩亍2還?孕"砝此擔?俣韌ǔ2皇俏侍狻?
內存帶寬。當CPU要將更多的數據存放在CPU緩存中時,主內存的帶寬就是瓶頸了。在大多數系統中,這不是常見的瓶頸,不過也是要注意的一個因素。
1.1 MySQL 設計的局限性
當使用MyISAM存儲引擎時,MySQL會使用一個快速數據表鎖以允許同時多個讀取和一個寫入。這種存儲引擎的最大問題是發生在一個單一的表上同時做穩定的更新操作及慢速查詢。如果這種情況在某個表中存在,可以使用另一種表類型。詳情請看"15 MySQL Storage Engines and Table Types"。
MySQL可以同時在事務及非事務表下工作。為了能夠平滑的使用非事務表(發生錯誤時不能回滾),有以下幾條規則:
所有的字段都有默認值
如果字段中插入了一個"錯誤"的值,比如在數字類型字段中插入過大數值,那麼MySQL會將該字段值置為"最可能的值"而不是給出一個錯誤。數字類型的值是0,最小或者最大的可能值。字符串類型,不是空字符串就是字段所能存儲的最大長度。
所有的計算表達式都會返回一個值而報告條件錯誤,例如 1/0 返回 NULL。
這些規則隱含的意思是,不能使用MySQL來檢查字段內容。相反地,必須在存儲到數據庫前在應用程序中來檢查。詳情請看"1.8.6 How MySQL Deals with Constraints 和 "14.1.4 INSERT Syntax"。
1.2 應用設計的可移植性
由於各種不同的數據庫實現了各自的SQL標准,這就需要我們盡量使用可移植的SQL應用。查詢和插入操作很容易就能做到可移植,不過由於更多的約束條件的要求就越發困難。想要讓一個應用在各種數據庫系統上快速運行,就變得更困難了。
為了能讓一個復雜的應用做到可移植,就要先看這個應用運行於哪種數據庫系統之上,然後看這些數據庫系統都支持哪些特性。
每個數據庫系統都有某些不足。也就是說,由於設計上的一些妥協,導致了性能上的差異。
可以用MySQL的 crash-me 程序來看選定的數據庫服務器上可以使用的函數,類型,限制等。crash-me 不會檢查各種可能存在的特性,不過這仍然是合乎情理的理解,大約做了450次測試。
一個 crash-me 的信息類型的例子就是,它會告訴您如果想使用Informix 或 DB2的話,就不能使字段名長度超過18個字符。
crash-me 程序和MySQL基准使每個准數據庫都實現了的。可以通過閱讀這些基准程序是怎麼寫的,自己就大概有怎樣做才能讓程序獨立於各種數據庫這方面的想法了。這些程序可以在MySQL源代碼的 `sql-bench' 目錄下找到。他們大部分都是用Perl寫的,並且使用DBI接口。由於它提供了獨立於數據庫的各種訪問方式,因此用DBI來解決各種移植性的問題。