數(shù)據(jù)庫優(yōu)化是一項(xiàng)很復(fù)雜的工作,因?yàn)檫@最終需要對系統(tǒng)優(yōu)化的很好理解才行。盡管對系統(tǒng)或應(yīng)用系統(tǒng)的了解不多的情況下優(yōu)化效果還不錯,但是如果想優(yōu)化的效果更好,那么就需要對它了解更多才行。 1、優(yōu)化概述 讓系統(tǒng)運(yùn)行得快得最重要因素是數(shù)據(jù)庫基本的設(shè)計。并
數(shù)據(jù)庫優(yōu)化是一項(xiàng)很復(fù)雜的工作,因?yàn)檫@最終需要對系統(tǒng)優(yōu)化的很好理解才行。盡管對系統(tǒng)或應(yīng)用系統(tǒng)的了解不多的情況下優(yōu)化效果還不錯,但是如果想優(yōu)化的效果更好,那么就需要對它了解更多才行。
1、優(yōu)化概述
讓系統(tǒng)運(yùn)行得快得最重要因素是數(shù)據(jù)庫基本的設(shè)計。并且還必須清楚您的系統(tǒng)要用來做什么,以及存在的瓶頸。
最常見的系統(tǒng)瓶頸有以下幾種:
磁盤搜索。它慢慢地在磁盤中搜索數(shù)據(jù)塊。對現(xiàn)代磁盤來說,平時的搜索時間基本上小于10毫秒,因此理論上每秒鐘可以做100次磁盤搜索。這個時間對于全新的新磁盤來說提高的不多,并且對于只有一個表的情況也是如此。加快搜索時間的方法是將數(shù)據(jù)分開存放到多個磁盤中。
磁盤讀/寫。當(dāng)磁盤在正確的位置上時,就需要讀取數(shù)據(jù)。對現(xiàn)代磁盤來說,磁盤吞吐量至少是10-20MB/秒。這比磁盤搜索的優(yōu)化更容易,因?yàn)榭梢詮亩鄠€媒介中并行地讀取數(shù)據(jù)。
CPU周期。數(shù)據(jù)存儲在主內(nèi)存中(或者它已經(jīng)在主內(nèi)存中了),這就需要處理這些數(shù)據(jù)以得到想要的結(jié)果。
內(nèi)存帶寬。當(dāng)CPU要將更多的數(shù)據(jù)存放在CPU緩存中時,主內(nèi)存的帶寬就是瓶頸了。在大多數(shù)系統(tǒng)中,這不是常見的瓶頸,不過也是要注意的一個因素。
1.1 MySQL 設(shè)計的局限性
當(dāng)使用MyISAM存儲引擎時,MySQL會使用一個快速數(shù)據(jù)表鎖以允許同時多個讀取和一個寫入。這種存儲引擎的最大問題是發(fā)生在一個單一的表上同時做穩(wěn)定的更新操作及慢速查詢。如果這種情況在某個表中存在,可以使用另一種表類型。
MySQL可以同時在事務(wù)及非事務(wù)表下工作。為了能夠平滑的使用非事務(wù)表(發(fā)生錯誤時不能回滾),有以下幾條規(guī)則:
所有的字段都有默認(rèn)值
如果字段中插入了一個"錯誤"的值,比如在數(shù)字類型字段中插入過大數(shù)值,那么MySQL會將該字段值置為"最可能的值"而不是給出一個錯誤。數(shù)字類型的值是0,最小或者最大的可能值。字符串類型,不是空字符串就是字段所能存儲的最大長度。
所有的計算表達(dá)式都會返回一個值而報告條件錯誤,例如 1/0 返回 NULL。
這些規(guī)則隱含的意思是,不能使用MySQL來檢查字段內(nèi)容。相反地,必須在存儲到數(shù)據(jù)庫前在應(yīng)用程序中來檢查。
1.2 應(yīng)用設(shè)計的可移植性
由于各種不同的數(shù)據(jù)庫實(shí)現(xiàn)了各自的SQL標(biāo)準(zhǔn),這就需要我們盡量使用可移植的SQL應(yīng)用。查詢和插入操作很容易就能做到可移植,不過由于更多的約束條件的要求就越發(fā)困難。想要讓一個應(yīng)用在各種數(shù)據(jù)庫系統(tǒng)上快速運(yùn)行,就變得更困難了。
為了能讓一個復(fù)雜的應(yīng)用做到可移植,就要先看這個應(yīng)用運(yùn)行于哪種數(shù)據(jù)庫系統(tǒng)之上,然后看這些數(shù)據(jù)庫系統(tǒng)都支持哪些特性。每個數(shù)據(jù)庫系統(tǒng)都有某些不足。也就是說,由于設(shè)計上的一些妥協(xié),導(dǎo)致了性能上的差異。
可以用MySQL的 crash-me 程序來看選定的數(shù)據(jù)庫服務(wù)器上可以使用的函數(shù),類型,限制等。crash-me 不會檢查各種可能存在的特性,不過這仍然是合乎情理的理解,大約做了450次測試。一個crash-me 的信息類型的例子就是,它會告訴您如果想使用Informix 或 DB2的話,就不能使字段名長度超過18個字符。
crash-me 程序和MySQL基準(zhǔn)使每個準(zhǔn)數(shù)據(jù)庫都實(shí)現(xiàn)了的。可以通過閱讀這些基準(zhǔn)程序是怎么寫的,自己就大概有怎樣做才能讓程序獨(dú)立于各種數(shù)據(jù)庫這方面的想法了。這些程序可以在MySQL源代碼的 `sql-bench' 目錄下找到。他們大部分都是用Perl寫的,并且使用DBI接口。由于它提供了獨(dú)立于數(shù)據(jù)庫的各種訪問方式,因此用DBI來解決各種移植性的問題。
如果您想努力做到獨(dú)立于數(shù)據(jù)庫,這就需要對各種SQL服務(wù)器的瓶頸都有一些很好的想法。例如,MySQL對于 MyISAM 類型的表在檢索以及更新記錄時非常快,但是在有并發(fā)的慢速讀取及寫入記錄時卻有一定的問題。作為Oracle來說,它在訪問剛剛被更新的記錄時有很大的問題(直到結(jié)果被刷新到磁盤中)。事務(wù)數(shù)據(jù)庫一般地在從日志表中生成摘要表這方面的表現(xiàn)不怎么好,因?yàn)樵谶@種情況下,行記錄鎖幾乎沒用。
為了能讓應(yīng)用程序真正的做到獨(dú)立于數(shù)據(jù)庫,就必須把操作數(shù)據(jù)的接口定義的簡單且可擴(kuò)展。由于C++在很多系統(tǒng)上都可以使用,因此使用C++作為數(shù)據(jù)庫的基類結(jié)果很合適。
如果使用了某些數(shù)據(jù)庫獨(dú)有的特定功能(比如 REPLACE 語句就只在MySQL中獨(dú)有),這就需要通過編寫替代方法來在其他數(shù)據(jù)庫中實(shí)現(xiàn)這個功能。盡管這些替代方法可能會比較慢,但是它能讓其他數(shù)據(jù)庫實(shí)現(xiàn)同樣的功能。
在MySQL中,可以在查詢語句中使用 /*! */ 語法來增加MySQL特有的關(guān)鍵字。然而在很多其他數(shù)據(jù)庫中,/**/ 卻被當(dāng)成了注釋(并且被忽略)。
如果有時候更高的性能比數(shù)據(jù)結(jié)果的精確更重要,就像在一些Web應(yīng)用中那樣,這可以使用一個應(yīng)用層來緩存結(jié)果,這可能會有更高的性能。通過讓舊數(shù)據(jù)在一定時間后過期,來合理的更新緩存。這是處理負(fù)載高峰期時的一種方法,這種情況下,可以通過加大緩存容量和過期時間直到負(fù)載趨于正常。
這種情況下,建表信息中就要包含了初始化緩存的容量以及正常刷新數(shù)據(jù)表的頻率。一個實(shí)現(xiàn)應(yīng)用層緩存的可選方案是使用MySQL的查詢緩存(query cache)。啟用查詢緩存后,數(shù)據(jù)庫就會根據(jù)一些詳情來決定哪些結(jié)果可以被重用。它大大簡化了應(yīng)用程序。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com