?? manual_performance.html
字號:
<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>優化是一項復雜的任務,因為它最終需要對整個系統的理解。當用你的系統/應用的小知識做一些局部優化是可能的時候,你越想讓你的系統更優化,你必須知道它也越多。
</p>
<p>因此,本章將試圖解釋并給出優化MySQL的不同方法的一些例子。但是記住總是有某些(逐漸變難)是系統更快的方法留著去做。
</p>
<h2><a NAME="Optimize_Basics" HREF="manual_toc.html#Optimize_Basics">10.1 優化概述</a></h2>
<p>為了使一個系統更快的最重要部分當然是基本設計。你也需要知道你的系統將做這樣的事情,那就是你的瓶頸。
</p>
<p>最常見的瓶頸是:
<ul>
<li>磁盤尋道。磁盤花時間找到一個數據,用在1999年的現代磁盤其平均時間通常小于10ms,因此理論上我們能大約一秒尋道
1000
次。這個時間用新磁盤提高很慢并且很難對一個表優化。優化它的方法是將數據散布在多個磁盤上。
</li>
<li>當磁盤在我們需要讀數據的正確位置時,磁盤讀/寫。用1999年的現代,一個磁盤傳輸類似10-20Mb/s。這必尋道更容易優化,因為你能從多個磁盤并行地讀。
</li>
<li>CPU周期。當我們讀數據進內存時,(或如果它已經在那里)我們需要處理它以達到我們的結果。當我們有相對內存較小的表時,這是最常見的限制因素,但是用小表速度通常不是問題。
</li>
<li>內存帶寬。當CPU需要超出適合cpu緩存的數據時,緩存帶寬就成為內存的一個瓶頸。這是對大多數系統的一個不常見的瓶頸但是你應該知道它。
</li>
</ul>
<h2><a NAME="System" HREF="manual_toc.html#System">10.2 系統/編譯時和啟動參數的調節</a></h2>
<p>我們以系統級的東西開始,因為這些決策的某一些很早就做好了。在其他情況下,快速瀏覽這部分可能就夠了,因為它對大收獲并不重要,但是有一個關于在這個層次上收獲有多大的感覺總是好的。
</p>
<p>使用的缺省OS確實重要!為了最大程度地使用多CPU,應該使用Solaris(因為線程工作得確實不錯)或Linux(因為2.2本的核心又確實不錯的SMP支持)。而且在32位的機器上,Linux缺省有2G的文件大小限制。當新的文件系統被釋出時(
XFS ),希望這不久被修正。 </p>
<p>因為我們沒在很多平臺上運行生產MySQL,我們忠告你在可能選擇它前,測試你打算運行的平臺。
</p>
<p>其他建議:
<ul>
<li>如果你有足夠的RAM,你能刪除所有交換設備。一些操作系統在某些情況下將使用一個SWAP設備,即使你有空閑的內存。
</li>
<li>使用<code>--skip-locking</code>的<strong>MySQL</strong>選項避免外部鎖定。注意這將不影響<strong>MySQL</strong>功能,只要它僅運行在一個服務器上。只要在你運行<code>myisamchk</code>以前,記得要停掉服務器(或鎖定相關部分)。在一些系統上這個開關是強制的,因為外部鎖定不是在任何情況下都工作。當用MIT-pthreads編譯時,<code>--skip-locking</code>選項缺省為打開(on),因為<code>flock()</code>沒在所有的平臺上被MIT-pthreads充分支持。唯一的情況是如果你對同一數據運行<strong>MySQL</strong>服務器(不是客戶),你不能使用<code>--skip-locking</code>之時,否則對沒有先清掉(flushing)或先鎖定<code>mysqld</code>服務器的表上運行<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>大多數下列測試在Linux上并用<strong>MySQL</strong>基準進行的,但是它們應該對其他操作系統和工作負載給出一些指示。
</p>
<p>當你用<code>-static</code>鏈接時,你得到最快的可執行文件。使用Unix套接字而非TCP/IP連接一個數據庫也可給出好一些的性能。
</p>
<p>在Linux上,當用<code>pgcc</code>和<code>-O6</code>編譯時,你將得到最快的代碼。為了用這些選項編譯<tt>“sql_yacc.cc”</tt>,你需要大約200M內存,因為<code>gcc/pgcc</code>需要很多內存使所有函數嵌入(inline)。在配置<strong>MySQL</strong>時,你也應該設定<code>CXX=gcc</code>以避免包括<code>libstdc++</code>庫(它不需要)。
</p>
<p>只通過使用一個較好的編譯器或較好的編譯器選項,在應用中你能得到一個10-30%的加速。如果你自己編譯SQL服務器,這特別重要!
</p>
<p>在Intel上,你應該例如使用pgcc或Cygnus CodeFusion編譯器得到最大速度。我們已經測試了新的
Fujitsu編譯器,但是它是還沒足夠不出錯來優化編譯MySQL。 </p>
<p>這里是我們做過的一些測量表:
<ul>
<li>如果你以<code>-O6</code>使用<code>pgcc</code>并且編譯任何東西,<code>mysqld</code>服務器是比用<code>gcc</code>快11%(用字符串99的版本)。
</li>
<li>如果你動態地鏈接(沒有<code>-static</code>),結果慢了13%。注意你仍能使用一個動態連接的MySQL庫。只有服務器對性能是關鍵的。
</li>
<li>如果你使用TCP/IP而非Unix套接字,結果慢7.5%。 </li>
<li>在一個Sun SPARCstation 10上,<code>gcc</code>2.7.3是比Sun Pro C++ 4.2快13%。 </li>
<li>在Solaris 2.5.1上,在單個處理器上MIT-pthreads比帶原生線程的Solaris慢8-12%。以更多的負載/cpus,差別應該變得更大。
</li>
</ul>
<p>由TcX提供的<strong>MySQL</strong>-Linux的分發用<code>pgcc</code>編譯并靜態鏈接。
</p>
<h3><a NAME="Disk_issues" HREF="manual_toc.html#Disk_issues">10.2.2 磁盤問題</a></h3>
<ul>
<li>正如前面所述,磁盤尋道是一個性能的大瓶頸。當數據開始增長以致緩存變得不可能時,這個問題變得越來越明顯。對大數據庫,在那你或多或少地要隨機存取數據,你可以依靠你將至少需要一次磁盤尋道來讀取并且幾次磁盤尋道寫入。為了使這個問題最小化,使用有低尋道時間的磁盤。
</li>
<li>為了增加可用磁盤軸的數量(并且從而減少尋道開銷),符號聯接文件到不同磁盤或分割磁盤是可能的。
<dl COMPACT="Disk_issues">
<dt><strong>使用符號連接</strong> </dt>
<dd>這意味著你將索引/數據文件符號從正常的數據目錄鏈接到其他磁盤(那也可以被分割的)。這使得尋道和讀取時間更好(如果磁盤不用于其他事情)。見<a HREF="manual_Performance.html#Symbolic_links">10.2.2.1
使用數據庫和表的符號鏈接</a>。 </dd>
<dt><strong>分割</strong> </dt>
<dd>分割意味著你有許多磁盤并把第一塊放在第一個磁盤上,在第二塊放在第二個磁盤上,并且第
n塊在第(n mod number_of_disks)磁盤上,等等。這意味著,如果你的正常數據大小于分割大小(或完美地排列過),你將得到較好一些的性能。注意,分割是否很依賴于OS和分割大小。因此用不同的分割大小測試你的應用程序。見<a HREF="manual_Performance.html#Benchmarks">10.8 使用你自己的基準</a>。注意對分割的速度差異<strong>很</strong>依賴于參數,取決于你如何分割參數和磁盤數量,你可以得出以數量級的不同。注意你必須選擇為隨機或順序存取優化。
</dd>
</dl>
</li>
<li>為了可靠,你可能想要使用襲擊RAID 0+1(分割+鏡像),但是在這種情況下,你將需要2*N個驅動器來保存N個驅動器的數據。如果你有錢,這可能是最好的選擇!然而你也可能必須投資一些卷管理軟件投資以高效地處理它。
</li>
<li>一個好選擇是讓稍重要的數據(它能再生)上存在RAID 0磁盤上,而將確實重要的數據(像主機信息和日志文件)存在一個RAID
0+1或RAID N磁盤上。如果因為更新奇偶位你有許多寫入,RAID N可能是一個問題。
</li>
<li>你也可以對數據庫使用的文件系統設置參數。一個容易的改變是以noatime選項掛裝文件系統。這是它跳過更新在inode中的最后訪問時間,而且這將避免一些磁盤尋道。</li>
</ul>
<h4><a NAME="Symbolic_links" HREF="manual_toc.html#Symbolic_links">10.2.2.1
為數據庫和表使用符號鏈接</a></h4>
<p>你可以從數據庫目錄移動表和數據庫到別處,并且用鏈接到新地點的符號代替它們。你可能想要這樣做,例如,轉移一個數據庫到有更多空閑空間的一個文件系統。
</p>
<p>如果<strong>MySQL</strong>注意到一個表是一個符號鏈接,它將解析符號鏈接并且使用其實際指向的表,它可工作在支持<code>realpath()</code>調用的所有系統上(至少Linux和Solaris支持<code>realpath()</code>)!在不支持<code>realpath()</code>的系統上,你應該不同時通過真實路徑和符號鏈接訪問表!如果你這樣做,表在任何更新后將不一致。
</p>
<p><strong>MySQL</strong>缺省不支持數據庫鏈接。只要你不在數據庫之間做一個符號鏈接,一切將工作正常。假定你在<strong>MySQL</strong>數據目錄下有一個數據庫<code>db1</code>,并且做了一個符號鏈接<code>db2</code>指向<code>db1</code>:</p>
<pre>shell> cd /path/to/datadir
shell> ln -s db1 db2
</pre>
<p>現在,對在<code>db1</code>中的任一表<code>tbl_a</code>,在<code>db2</code>種也好象有一個表<code>tbl_a</code>。如果一個線程更新<code>db1.tbl_a</code>并且另一個線程更新<code>db2.tbl_a</code>,將有問題。
</p>
<p>如果你確實需要這樣,你必須改變下列在<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>把代碼改變為這樣: </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
調節服務器參數</a></h3>
<p>你能用這個命令得到<code>mysqld</code>服務器缺省緩沖區大?。?</p>
<pre>shell> mysqld --help
</pre>
<p>這個命令生成一張所有<code>mysqld</code>選項和可配置變量的表。輸出包括缺省值并且看上去象這樣一些東西:
</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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -