?? manual_performance.html
字號(hào):
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
<title>MySQL中文參考手冊- 10 從MySQL得到最大的性能</title>
<style type="text/css">
<!--
.p14{font-size:14.8px;font-family:宋體;line-height:14pt;}
.p5{ border: 1px solid rgb(146,201,201) }
a:hover{color:red;}
a.t1:visited{color:red;}
-->
</style>
</head>
<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#101090" VLINK="#7030B0" class="p4">
<h1><img src="Img/mysql-logo.gif" alt="mysql-logo.gif (3082 bytes)" WIDTH="127" HEIGHT="60"><font color="#FF0000">MySQL中文參考手冊</font></h1>
<p>譯者:晏子 <a href="mailto:(clyan@sohu.com">(clyan@sohu.com</a>)
主頁:<a href="http://linuxdb.yeah.net">http://linuxdb.yeah.net</a></p>
<hr>
<p><a HREF="manual_Introduction.html">第一章</a>, <a HREF="manual_Server.html">前一章</a>,
<a HREF="manual_MySQL_Benchmarks.html">下一章</a>, <a HREF="manual_Concept_Index.html">最后一章</a>,<a HREF="manual_toc.html">目錄</a>. </p>
<hr>
<h1><a NAME="Performance" HREF="manual_toc.html#Performance">10 從MySQL得到最大的性能</a></h1>
<p>優(yōu)化是一項(xiàng)復(fù)雜的任務(wù),因?yàn)樗罱K需要對(duì)整個(gè)系統(tǒng)的理解。當(dāng)用你的系統(tǒng)/應(yīng)用的小知識(shí)做一些局部優(yōu)化是可能的時(shí)候,你越想讓你的系統(tǒng)更優(yōu)化,你必須知道它也越多。
</p>
<p>因此,本章將試圖解釋并給出優(yōu)化MySQL的不同方法的一些例子。但是記住總是有某些(逐漸變難)是系統(tǒng)更快的方法留著去做。
</p>
<h2><a NAME="Optimize_Basics" HREF="manual_toc.html#Optimize_Basics">10.1 優(yōu)化概述</a></h2>
<p>為了使一個(gè)系統(tǒng)更快的最重要部分當(dāng)然是基本設(shè)計(jì)。你也需要知道你的系統(tǒng)將做這樣的事情,那就是你的瓶頸。
</p>
<p>最常見的瓶頸是:
<ul>
<li>磁盤尋道。磁盤花時(shí)間找到一個(gè)數(shù)據(jù),用在1999年的現(xiàn)代磁盤其平均時(shí)間通常小于10ms,因此理論上我們能大約一秒尋道
1000
次。這個(gè)時(shí)間用新磁盤提高很慢并且很難對(duì)一個(gè)表優(yōu)化。優(yōu)化它的方法是將數(shù)據(jù)散布在多個(gè)磁盤上。
</li>
<li>當(dāng)磁盤在我們需要讀數(shù)據(jù)的正確位置時(shí),磁盤讀/寫。用1999年的現(xiàn)代,一個(gè)磁盤傳輸類似10-20Mb/s。這必尋道更容易優(yōu)化,因?yàn)槟隳軓亩鄠€(gè)磁盤并行地讀。
</li>
<li>CPU周期。當(dāng)我們讀數(shù)據(jù)進(jìn)內(nèi)存時(shí),(或如果它已經(jīng)在那里)我們需要處理它以達(dá)到我們的結(jié)果。當(dāng)我們有相對(duì)內(nèi)存較小的表時(shí),這是最常見的限制因素,但是用小表速度通常不是問題。
</li>
<li>內(nèi)存帶寬。當(dāng)CPU需要超出適合cpu緩存的數(shù)據(jù)時(shí),緩存帶寬就成為內(nèi)存的一個(gè)瓶頸。這是對(duì)大多數(shù)系統(tǒng)的一個(gè)不常見的瓶頸但是你應(yīng)該知道它。
</li>
</ul>
<h2><a NAME="System" HREF="manual_toc.html#System">10.2 系統(tǒng)/編譯時(shí)和啟動(dòng)參數(shù)的調(diào)節(jié)</a></h2>
<p>我們以系統(tǒng)級(jí)的東西開始,因?yàn)檫@些決策的某一些很早就做好了。在其他情況下,快速瀏覽這部分可能就夠了,因?yàn)樗鼘?duì)大收獲并不重要,但是有一個(gè)關(guān)于在這個(gè)層次上收獲有多大的感覺總是好的。
</p>
<p>使用的缺省OS確實(shí)重要!為了最大程度地使用多CPU,應(yīng)該使用Solaris(因?yàn)榫€程工作得確實(shí)不錯(cuò))或Linux(因?yàn)?.2本的核心又確實(shí)不錯(cuò)的SMP支持)。而且在32位的機(jī)器上,Linux缺省有2G的文件大小限制。當(dāng)新的文件系統(tǒng)被釋出時(shí)(
XFS ),希望這不久被修正。 </p>
<p>因?yàn)槲覀儧]在很多平臺(tái)上運(yùn)行生產(chǎn)MySQL,我們忠告你在可能選擇它前,測試你打算運(yùn)行的平臺(tái)。
</p>
<p>其他建議:
<ul>
<li>如果你有足夠的RAM,你能刪除所有交換設(shè)備。一些操作系統(tǒng)在某些情況下將使用一個(gè)SWAP設(shè)備,即使你有空閑的內(nèi)存。
</li>
<li>使用<code>--skip-locking</code>的<strong>MySQL</strong>選項(xiàng)避免外部鎖定。注意這將不影響<strong>MySQL</strong>功能,只要它僅運(yùn)行在一個(gè)服務(wù)器上。只要在你運(yùn)行<code>myisamchk</code>以前,記得要停掉服務(wù)器(或鎖定相關(guān)部分)。在一些系統(tǒng)上這個(gè)開關(guān)是強(qiáng)制的,因?yàn)橥獠挎i定不是在任何情況下都工作。當(dāng)用MIT-pthreads編譯時(shí),<code>--skip-locking</code>選項(xiàng)缺省為打開(on),因?yàn)?lt;code>flock()</code>沒在所有的平臺(tái)上被MIT-pthreads充分支持。唯一的情況是如果你對(duì)同一數(shù)據(jù)運(yùn)行<strong>MySQL</strong>服務(wù)器(不是客戶),你不能使用<code>--skip-locking</code>之時(shí),否則對(duì)沒有先清掉(flushing)或先鎖定<code>mysqld</code>服務(wù)器的表上運(yùn)行<code>myisamchk</code>。你仍然能使用<code>LOCK
TABLES</code>/ <code>UNLOCK TABLES</code>,即使你正在使用<code>--skip-locking</code>。
</li>
</ul>
<h3><a NAME="Compile_and_link_options" HREF="manual_toc.html#Compile_and_link_options">10.2.1
編譯和鏈接怎樣影響MySQL的速度</a></h3>
<p>大多數(shù)下列測試在Linux上并用<strong>MySQL</strong>基準(zhǔn)進(jìn)行的,但是它們應(yīng)該對(duì)其他操作系統(tǒng)和工作負(fù)載給出一些指示。
</p>
<p>當(dāng)你用<code>-static</code>鏈接時(shí),你得到最快的可執(zhí)行文件。使用Unix套接字而非TCP/IP連接一個(gè)數(shù)據(jù)庫也可給出好一些的性能。
</p>
<p>在Linux上,當(dāng)用<code>pgcc</code>和<code>-O6</code>編譯時(shí),你將得到最快的代碼。為了用這些選項(xiàng)編譯<tt>“sql_yacc.cc”</tt>,你需要大約200M內(nèi)存,因?yàn)?lt;code>gcc/pgcc</code>需要很多內(nèi)存使所有函數(shù)嵌入(inline)。在配置<strong>MySQL</strong>時(shí),你也應(yīng)該設(shè)定<code>CXX=gcc</code>以避免包括<code>libstdc++</code>庫(它不需要)。
</p>
<p>只通過使用一個(gè)較好的編譯器或較好的編譯器選項(xiàng),在應(yīng)用中你能得到一個(gè)10-30%的加速。如果你自己編譯SQL服務(wù)器,這特別重要!
</p>
<p>在Intel上,你應(yīng)該例如使用pgcc或Cygnus CodeFusion編譯器得到最大速度。我們已經(jīng)測試了新的
Fujitsu編譯器,但是它是還沒足夠不出錯(cuò)來優(yōu)化編譯MySQL。 </p>
<p>這里是我們做過的一些測量表:
<ul>
<li>如果你以<code>-O6</code>使用<code>pgcc</code>并且編譯任何東西,<code>mysqld</code>服務(wù)器是比用<code>gcc</code>快11%(用字符串99的版本)。
</li>
<li>如果你動(dòng)態(tài)地鏈接(沒有<code>-static</code>),結(jié)果慢了13%。注意你仍能使用一個(gè)動(dòng)態(tài)連接的MySQL庫。只有服務(wù)器對(duì)性能是關(guān)鍵的。
</li>
<li>如果你使用TCP/IP而非Unix套接字,結(jié)果慢7.5%。 </li>
<li>在一個(gè)Sun SPARCstation 10上,<code>gcc</code>2.7.3是比Sun Pro C++ 4.2快13%。 </li>
<li>在Solaris 2.5.1上,在單個(gè)處理器上MIT-pthreads比帶原生線程的Solaris慢8-12%。以更多的負(fù)載/cpus,差別應(yīng)該變得更大。
</li>
</ul>
<p>由TcX提供的<strong>MySQL</strong>-Linux的分發(fā)用<code>pgcc</code>編譯并靜態(tài)鏈接。
</p>
<h3><a NAME="Disk_issues" HREF="manual_toc.html#Disk_issues">10.2.2 磁盤問題</a></h3>
<ul>
<li>正如前面所述,磁盤尋道是一個(gè)性能的大瓶頸。當(dāng)數(shù)據(jù)開始增長以致緩存變得不可能時(shí),這個(gè)問題變得越來越明顯。對(duì)大數(shù)據(jù)庫,在那你或多或少地要隨機(jī)存取數(shù)據(jù),你可以依靠你將至少需要一次磁盤尋道來讀取并且?guī)状未疟P尋道寫入。為了使這個(gè)問題最小化,使用有低尋道時(shí)間的磁盤。
</li>
<li>為了增加可用磁盤軸的數(shù)量(并且從而減少尋道開銷),符號(hào)聯(lián)接文件到不同磁盤或分割磁盤是可能的。
<dl COMPACT="Disk_issues">
<dt><strong>使用符號(hào)連接</strong> </dt>
<dd>這意味著你將索引/數(shù)據(jù)文件符號(hào)從正常的數(shù)據(jù)目錄鏈接到其他磁盤(那也可以被分割的)。這使得尋道和讀取時(shí)間更好(如果磁盤不用于其他事情)。見<a HREF="manual_Performance.html#Symbolic_links">10.2.2.1
使用數(shù)據(jù)庫和表的符號(hào)鏈接</a>。 </dd>
<dt><strong>分割</strong> </dt>
<dd>分割意味著你有許多磁盤并把第一塊放在第一個(gè)磁盤上,在第二塊放在第二個(gè)磁盤上,并且第
n塊在第(n mod number_of_disks)磁盤上,等等。這意味著,如果你的正常數(shù)據(jù)大小于分割大小(或完美地排列過),你將得到較好一些的性能。注意,分割是否很依賴于OS和分割大小。因此用不同的分割大小測試你的應(yīng)用程序。見<a HREF="manual_Performance.html#Benchmarks">10.8 使用你自己的基準(zhǔn)</a>。注意對(duì)分割的速度差異<strong>很</strong>依賴于參數(shù),取決于你如何分割參數(shù)和磁盤數(shù)量,你可以得出以數(shù)量級(jí)的不同。注意你必須選擇為隨機(jī)或順序存取優(yōu)化。
</dd>
</dl>
</li>
<li>為了可靠,你可能想要使用襲擊RAID 0+1(分割+鏡像),但是在這種情況下,你將需要2*N個(gè)驅(qū)動(dòng)器來保存N個(gè)驅(qū)動(dòng)器的數(shù)據(jù)。如果你有錢,這可能是最好的選擇!然而你也可能必須投資一些卷管理軟件投資以高效地處理它。
</li>
<li>一個(gè)好選擇是讓稍重要的數(shù)據(jù)(它能再生)上存在RAID 0磁盤上,而將確實(shí)重要的數(shù)據(jù)(像主機(jī)信息和日志文件)存在一個(gè)RAID
0+1或RAID N磁盤上。如果因?yàn)楦缕媾嘉荒阌性S多寫入,RAID N可能是一個(gè)問題。
</li>
<li>你也可以對(duì)數(shù)據(jù)庫使用的文件系統(tǒng)設(shè)置參數(shù)。一個(gè)容易的改變是以noatime選項(xiàng)掛裝文件系統(tǒng)。這是它跳過更新在inode中的最后訪問時(shí)間,而且這將避免一些磁盤尋道。</li>
</ul>
<h4><a NAME="Symbolic_links" HREF="manual_toc.html#Symbolic_links">10.2.2.1
為數(shù)據(jù)庫和表使用符號(hào)鏈接</a></h4>
<p>你可以從數(shù)據(jù)庫目錄移動(dòng)表和數(shù)據(jù)庫到別處,并且用鏈接到新地點(diǎn)的符號(hào)代替它們。你可能想要這樣做,例如,轉(zhuǎn)移一個(gè)數(shù)據(jù)庫到有更多空閑空間的一個(gè)文件系統(tǒng)。
</p>
<p>如果<strong>MySQL</strong>注意到一個(gè)表是一個(gè)符號(hào)鏈接,它將解析符號(hào)鏈接并且使用其實(shí)際指向的表,它可工作在支持<code>realpath()</code>調(diào)用的所有系統(tǒng)上(至少Linux和Solaris支持<code>realpath()</code>)!在不支持<code>realpath()</code>的系統(tǒng)上,你應(yīng)該不同時(shí)通過真實(shí)路徑和符號(hào)鏈接訪問表!如果你這樣做,表在任何更新后將不一致。
</p>
<p><strong>MySQL</strong>缺省不支持?jǐn)?shù)據(jù)庫鏈接。只要你不在數(shù)據(jù)庫之間做一個(gè)符號(hào)鏈接,一切將工作正常。假定你在<strong>MySQL</strong>數(shù)據(jù)目錄下有一個(gè)數(shù)據(jù)庫<code>db1</code>,并且做了一個(gè)符號(hào)鏈接<code>db2</code>指向<code>db1</code>:</p>
<pre>shell> cd /path/to/datadir
shell> ln -s db1 db2
</pre>
<p>現(xiàn)在,對(duì)在<code>db1</code>中的任一表<code>tbl_a</code>,在<code>db2</code>種也好象有一個(gè)表<code>tbl_a</code>。如果一個(gè)線程更新<code>db1.tbl_a</code>并且另一個(gè)線程更新<code>db2.tbl_a</code>,將有問題。
</p>
<p>如果你確實(shí)需要這樣,你必須改變下列在<tt>“mysys/mf_format.c”</tt>中的代碼:
</p>
<pre>if (!lstat(to,&stat_buff)) /* Check if it's a symbolic link */
if (S_ISLNK(stat_buff.st_mode) && realpath(to,buff))
</pre>
<p>把代碼改變?yōu)檫@樣: </p>
<pre>if (realpath(to,buff))
<a NAME="IDX620"></a> </pre>
<h3><a NAME="Server_parameters" HREF="manual_toc.html#Server_parameters">10.2.3
調(diào)節(jié)服務(wù)器參數(shù)</a></h3>
<p>你能用這個(gè)命令得到<code>mysqld</code>服務(wù)器缺省緩沖區(qū)大小: </p>
<pre>shell> mysqld --help
</pre>
<p>這個(gè)命令生成一張所有<code>mysqld</code>選項(xiàng)和可配置變量的表。輸出包括缺省值并且看上去象這樣一些東西:
</p>
<pre>Possible variables for option --set-variable (-O) are:
back_log current value: 5
connect_timeout current value: 5
delayed_insert_timeout current value: 300
delayed_insert_limit current value: 100
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -