1、咱們能夠且應該優化什麼?html
硬件mysql
操做系統/軟件庫ios
SQL服務器(設置和查詢)web
應用編程接口(API)sql
應用程序數據庫
--------------------------------------------------------------------------------編程
2、優化硬件緩存
若是你須要龐大的數據庫表(>2G),你應該考慮使用64位的硬件結構,像Alpha、Sparc或即將推出的IA64。由於MySQL內部使用大量64位的整數,64位的CPU將提供更好的性能。安全
對大數據庫,優化的次序通常是RAM、快速硬盤、CPU能力。服務器
更多的內存經過將最經常使用的鍵碼頁面存放在內存中能夠加速鍵碼的更新。
若是不使用事務安全(transaction-safe)的表或有大表而且想避免長文件檢查,一臺UPS就可以在電源故障時讓系統安全關閉。
對於數據庫存放在一個專用服務器的系統,應該考慮1G的以太網。延遲與吞吐量一樣重要。
--------------------------------------------------------------------------------
3、優化磁盤
爲系統、程序和臨時文件配備一個專用磁盤,若是確是進行不少修改工做,將更新日誌和事務日誌放在專用磁盤上。 低尋道時間對數據庫磁盤很是重要。對與大表,你能夠估計你將須要log(行數)/log(索引塊長度/3*2/(鍵碼長度 + 數據指針長度))+1次尋到才能找到一行。對於有500000行的表,索引Mediun int類型的列,須要log(500000) / log(1024/3*2/(3 + 2))+1=4次尋道。上述索引須要500000*7*3/2=5.2M的空間。實際上,大多數塊將被緩存,因此大概只須要1-2次尋道。 然而對於寫入(如上),你將須要4次尋道請求來找到在哪裏存放新鍵碼,並且通常要2次尋道來更新索引並寫入一行。 對於很是大的數據庫,你的應用將受到磁盤尋道速度的限制,隨着數據量的增長呈N log N數據級遞增。 將數據庫和表分在不一樣的磁盤上。在MySQL中,你能夠爲此而使用符號連接。 條列磁盤(RAID 0)將提升讀和寫的吞吐量。 帶鏡像的條列(RAID 0+1)將更安全並提升讀取的吞吐量。寫入的吞吐量將有所下降。 不要對臨時文件或能夠很容易地重建的數據所在的磁盤使用鏡像或RAID(除了RAID 0)。 在Linux上,在引導時對磁盤使用命令hdparm -m16 -d1以啓用同時讀寫多個扇區和DMA功能。這能夠將響應時間提升5~50%。 在Linux上,用async (默認)和noatime掛載磁盤(mount)。 對於某些特定應用,能夠對某些特定表使用內存磁盤,但一般不須要。
--------------------------------------------------------------------------------
4、優化操做系統
不要交換區。若是內存不足,增長更多的內存或配置你的系統使用較少內存。 不要使用NFS磁盤(會有NFS鎖定的問題)。 增長系統和MySQL服務器的打開文件數量。(在safe_mysqld腳本中加入ulimit -n #)。 增長系統的進程和線程數量。 若是你有相對較少的大表,告訴文件系統不要將文件打碎在不一樣的磁道上(Solaris)。 使用支持大文件的文件系統(Solaris)。 選擇使用哪一種文件系統。在Linux上的Reiserfs對於打開、讀寫都很是快。文件檢查只需幾秒種。
--------------------------------------------------------------------------------
5、選擇應用編程接口
PERL 可在不一樣的操做系統和數據庫之間移植。 適宜快速原型。 應該使用DBI/DBD接口。 PHP 比PERL易學。 使用比PERL少的資源。 經過升級到PHP4能夠得到更快的速度。 C MySQL的原生接口。 較快並賦予更多的控制。 低層,因此必須付出更多。 C++ 較高層次,給你更多的時間來編寫應用。 仍在開發中 ODBC 運行在Windows和Unix上。 幾乎可在不一樣的SQL服務器間移植。 較慢。MyODBC只是簡單的直通驅動程序,比用原生接口慢19%。 有不少方法作一樣的事。很難像不少ODBC驅動程序那樣運行,在不一樣的領域還有不一樣的錯誤。 問題成堆。Microsoft偶爾還會改變接口。 不明朗的將來。(Microsoft更推崇OLE而非ODBC) ODBC 運行在Windows和Unix上。 幾乎可在不一樣的SQL服務器間移植。 較慢。MyODBC只是簡單的直通驅動程序,比用原生接口慢19%。 有不少方法作一樣的事。很難像不少ODBC驅動程序那樣運行,在不一樣的領域還有不一樣的錯誤。 問題成堆。Microsoft偶爾還會改變接口。 不明朗的將來。(Microsoft更推崇OLE而非ODBC) JDBC 理論上可在不一樣的操做系統什麼時候據庫間移植。 能夠運行在web客戶端。 Python和其餘 可能不錯,可咱們不用它們。
--------------------------------------------------------------------------------
6、優化應用
應該集中精力解決問題。 在編寫應用時,應該決定什麼是最重要的: 速度 操做系統間的可移植性 SQL服務器間的可移植性 使用持續的鏈接。. 緩存應用中的數據以減小SQL服務器的負載。 不要查詢應用中不須要的列。 不要使用SELECT * FROM table_name... 測試應用的全部部分,但將大部分精力放在在可能最壞的合理的負載下的測試總體應用。經過以一種模塊化的方式進行,你應該能用一個快速「啞模塊」替代找到的瓶頸,而後很容易地標出下一個瓶頸。 若是在一個批處理中進行大量修改,使用LOCK TABLES。例如將多個UPDATES或DELETES集中在一塊兒。
--------------------------------------------------------------------------------
7、應該使用可移植的應用
Perl DBI/DBD ODBC JDBC Python(或其餘有廣泛SQL接口的語言) 你應該只使用存在於全部目的SQL服務器中或能夠很容易地用其餘構造模擬的SQL構造。www.mysql.com上的Crash-me頁能夠幫助你。 爲操做系統/SQL服務器編寫包裝程序來提供缺乏的功能。
--------------------------------------------------------------------------------
8、若是你須要更快的速度,你應該:
找出瓶頸(CPU、磁盤、內存、SQL服務器、操做系統、API或應用)並集中全力解決。 使用給予你更快速度/靈活性的擴展。 逐漸瞭解SQL服務器以便能爲你的問題使用可能最快的SQL構造並避免瓶頸。 優化表佈局和查詢。 使用複製以得到更快的選擇(select)速度。 若是你有一個慢速的網絡鏈接數據庫,使用壓縮客戶/服務器協議。 不要懼怕時應用的第一個版本不能完美地移植,在你解決問題時,你老是能夠在之後優化它。
--------------------------------------------------------------------------------
9、優化MySQL
挑選編譯器和編譯選項。 位你的系統尋找最好的啓動選項。 通讀MySQL參考手冊並閱讀Paul DuBios的《MySQL》一書。(已有中文版-譯註) 多用EXPLAIN SELECT、SHOW VARIABLES、SHOW STATUS和SHOW PROCESSLIST。 瞭解查詢優化器的工做原理。 優化表的格式。 維護你的表(myisamchk、CHECK TABLE、 OPTIMIZE TABLE) 使用MySQL的擴展功能以讓一切快速完成。 若是你注意到了你將在不少場合須要某些函數,編寫MySQL UDF函數。 不要使用表級或列級的GRANT,除非你確實須要。 購買MySQL技術支持以幫助你解決問題憨笑
--------------------------------------------------------------------------------
10、編譯和安裝MySQL
經過位你的系統挑選可能最好的編譯器,你一般能夠得到10-30%的性能提升。 在Linux/Intel平臺上,用pgcc(gcc的奔騰芯片優化版)編譯MySQL。然而,二進制代碼將只能運行在Intel奔騰CPU上。 對於一種特定的平臺,使用MySQL參考手冊上推薦的優化選項。 通常地,對特定CPU的原生編譯器(如Sparc的Sun Workshop)應該比gcc提供更好的性能,但不老是這樣。 用你將使用的字符集編譯MySQL。 靜態編譯生成mysqld的執行文件(用--with-mysqld-ldflags=all-static)並用strip sql/mysqld整理最終的執行文件。 注意,既然MySQL不使用C++擴展,不帶擴展支持編譯MySQL將贏得巨大的性能提升。 若是操做系統支持原生線程,使用原生線程(而不用mit-pthreads)。 用MySQL基準測試來測試最終的二進制代碼。
--------------------------------------------------------------------------------
11、維護
若是可能,偶爾運行一下OPTIMIZE table,這對大量更新的變長行很是重要。 偶爾用myisamchk -a更新一下表中的鍵碼分佈統計。記住在作以前關掉MySQL。 若是有碎片文件,可能值得將全部文件複製到另外一個磁盤上,清除原來的磁盤並拷迴文件。 若是遇到問題,用myisamchk或CHECK table檢查表。 用mysqladmin -i10 precesslist extended-status監控MySQL的狀態。 用MySQL GUI客戶程序,你能夠在不一樣的窗口內監控進程列表和狀態。 使用mysqladmin debug得到有關鎖定和性能的信息。
--------------------------------------------------------------------------------
12、優化SQL
揚SQL之長,其它事情交由應用去作。使用SQL服務器來作:
找出基於WHERE子句的行。 JOIN表 GROUP BY ORDER BY DISTINCT
不要使用SQL來作:
檢驗數據(如日期) 成爲一隻計算器
技巧:
明智地使用鍵碼。 鍵碼適合搜索,但不適合索引列的插入/更新。 保持數據爲數據庫第三範式,但不要擔憂冗餘信息或這若是你須要更快的速度,建立總結表。 在大表上不作GROUP BY,相反建立大表的總結表並查詢它。 UPDATE table set count=count+1 where key_column=constant很是快。 對於大表,或許最好偶爾生成總結表而不是一直保持總結表。 充分利用INSERT的默認值。
--------------------------------------------------------------------------------
十3、不一樣SQL服務器的速度差異(以秒計)
+--------------------------+--------+---------+ |經過鍵碼讀取2000000行: | NT | Linux | +--------------------------+--------+---------+ |mysql | 367 | 249 | +--------------------------+--------+---------+ |mysql_odbc | 464 | | +--------------------------+--------+---------+ |db2_odbc | 1206 | | +--------------------------+--------+---------+ |informix_odbc | 121126 | | +--------------------------+--------+---------+ |ms-sql_odbc | 1634 | | +--------------------------+--------+---------+ |oracle_odbc | 20800 | | +--------------------------+--------+---------+ |solid_odbc | 877 | | +--------------------------+--------+---------+ |sybase_odbc | 17614 | | +--------------------------+--------+---------+
+--------------------------+--------+---------+ |插入350768行: | NT | Linux | +--------------------------+--------+---------+ |mysql | 381 | 206 | +--------------------------+--------+---------+ |mysql_odbc | 619 | | +--------------------------+--------+---------+ |db2_odbc | 3460 | | +--------------------------+--------+---------+ |informix_odbc | 2692 | | +--------------------------+--------+---------+ |ms-sql_odbc | 4012 | | +--------------------------+--------+---------+ |oracle_odbc | 11291 | | +--------------------------+--------+---------+ |solid_odbc | 1801 | | +--------------------------+--------+---------+ |sybase_odbc | 4802 | | +--------------------------+--------+---------+
在上述測試中,MySQL配置8M高速緩存運行,其餘數據庫以默認安裝運行。
--------------------------------------------------------------------------------
十4、重要的MySQL啓動選項
back_log 若是須要大量新鏈接,修改它。 thread_cache_size 若是須要大量新鏈接,修改它。 key_buffer_size 索引頁池,能夠設成很大。 bdb_cache_size BDB表使用的記錄和鍵嗎高速緩存。 table_cache 若是有不少的表和併發鏈接,修改它。 delay_key_write 若是須要緩存全部鍵碼寫入,設置它。 log_slow_queries 找出需花大量時間的查詢。 max_heap_table_size 用於GROUP BY sort_buffer 用於ORDER BY和GROUP BY myisam_sort_buffer_size 用於REPAIR TABLE join_buffer_size 在進行無鍵嗎的聯結時使用。
--------------------------------------------------------------------------------
十5、優化表
MySQL擁有一套豐富的類型。你應該對每一列嘗試使用最有效的類型。 ANALYSE過程能夠幫助你找到表的最優類型:SELECT * FROM table_name PROCEDURE ANALYSE()。 對於不保存NULL值的列使用NOT NULL,這對你想索引的列尤爲重要。 將ISAM類型的表改成MyISAM。 若是可能,用固定的表格式建立表。 不要索引你不想用的東西。 利用MySQL能按一個索引的前綴進行查詢的事實。若是你有索引INDEX(a,b),你不須要在a上的索引。 不在長CHAR/VARCHAR列上建立索引,而只索引列的一個前綴以節省存儲空間。CREATE TABLE table_name (hostname CHAR(255) not null, index(hostname(10))) 對每一個表使用最有效的表格式。 在不一樣表中保存相同信息的列應該有一樣的定義並具備相同的列名。
--------------------------------------------------------------------------------
十6、MySQL如何次存儲數據
數據庫以目錄存儲。 表以文件存儲。 列以變長或定長格式存儲在文件中。對BDB表,數據以頁面形式存儲。 支持基於內存的表。 數據庫和表可在不一樣的磁盤上用符號鏈接起來。 在Windows上,MySQL支持用.sym文件內部符號鏈接數據庫。
--------------------------------------------------------------------------------
十7、MySQL表類型
HEAP表:固定行長的表,只存儲在內存中並用HASH索引進行索引。 ISAM表:MySQL 3.22中的早期B-tree表格式。 MyIASM:IASM表的新版本,有以下擴展: 二進制層次的可移植性。 NULL列索引。 對變長行比ISAM表有更少的碎片。 支持大文件。 更好的索引壓縮。 更好的鍵嗎統計分佈。 更好和更快的auto_increment處理。 來自Sleepcat的Berkeley DB(BDB)表:事務安全(有BEGIN WORK/COMMIT|ROLLBACK)。
--------------------------------------------------------------------------------
十8、MySQL行類型(專指IASM/MyIASM表)
若是全部列是定長格式(沒有VARCHAR、BLOB或TEXT),MySQL將以定長表格式建立表,不然表以動態長度格式建立。 定長格式比動態長度格式快不少並更安全。 動態長度行格式通常佔用較少的存儲空間,但若是表頻繁更新,會產生碎片。 在某些狀況下,不值得將全部VARCHAR、BLOB和TEXT列轉移到另外一個表中,只是得到主表上的更快速度。 利用myiasmchk(對ISAM,pack_iasm),能夠建立只讀壓縮表,這使磁盤使用率最小,但使用慢速磁盤時,這很是不錯。壓縮表充分地利用將再也不更新的日誌表
--------------------------------------------------------------------------------
十9、MySQL高速緩存(全部線程共享,一次性分配)
鍵碼緩存:key_buffer_size,默認8M。 表緩存:table_cache,默認64。 線程緩存:thread_cache_size,默認0。 主機名緩存:可在編譯時修改,默認128。 內存映射表:目前僅用於壓縮表。 注意:MySQL沒有運行高速緩存,而讓操做系統處理。
--------------------------------------------------------------------------------
二10、MySQL緩存區變量(非共享,按需分配)
sort_buffer:ORDER BY/GROUP BY record_buffer:掃描表。 join_buffer_size:無鍵聯結 myisam_sort_buffer_size:REPAIR TABLE net_buffer_length:對於讀SQL語句並緩存結果。 tmp_table_size:臨時結果的HEAP表大小。
--------------------------------------------------------------------------------
二11、MySQL表高速緩存工做原理
每一個MyISAM表的打開實例(instance)使用一個索引文件和一個數據文件。若是表被兩個線程使用或在同一條查詢中使用兩次,MyIASM將共享索引文件而是打開數據文件的另外一個實例。 若是全部在高速緩存中的表都在使用,緩存將臨時增長到比表緩存尺寸大些。若是是這樣,下一個被釋放的表將被關閉。 你能夠經過檢查mysqld的Opened_tables變量以檢查表緩存是否過小。若是該值過高,你應該增大表高速緩存。
--------------------------------------------------------------------------------
二12、MySQL擴展/優化-提供更快的速度
使用優化的表類型(HEAP、MyIASM或BDB表)。 對數據使用優化的列。 若是可能使用定長行。 使用不一樣的鎖定類型(SELECT HIGH_PRIORITY,INSERT LOW_PRIORITY) Auto_increment REPLACE (REPLACE INTO table_name VALUES (...)) INSERT DELAYED LOAD DATA INFILE / LOAD_FILE() 使用多行INSERT一次插入多行。 SELECT INTO OUTFILE LEFT JOIN, STRAIGHT JOIN LEFT JOIN ,結合IS NULL ORDER BY可在某些狀況下使用鍵碼。 若是隻查詢在一個索引中的列,將只使用索引樹解決查詢。 聯結通常比子查詢快(對大多數SQL服務器亦如此)。 LIMIT SELECT * from table1 WHERE a > 10 LIMIT 10,20 DELETE * from table1 WHERE a > 10 LIMIT 10 foo IN (常數列表) 高度優化。 GET_LOCK()/RELEASE_LOCK() LOCK TABLES INSERT和SELECT可同時運行。 UDF函數可裝載進一個正在運行的服務器。 壓縮只讀表。 CREATE TEMPORARY TABLE CREATE TABLE .. SELECT 帶RAID選項的MyIASM表將文件分割成不少文件以突破某些文件系統的2G限制。 Delay_keys 複製功能
--------------------------------------------------------------------------------
二12、MySQL什麼時候使用索引
對一個鍵碼使用>, >=, =, <, <=, IF NULL和BETWEEN SELECT * FROM table_name WHERE key_part1=1 and key_part2 > 5; SELECT * FROM table_name WHERE key_part1 IS NULL;
當使用不以通配符開始的LIKE SELECT * FROM table_name WHERE key_part1 LIKE 'jani%'
在進行聯結時從另外一個表中提取行時 SELECT * from t1,t2 where t1.col=t2.key_part
找出指定索引的MAX()或MIN()值 SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10
一個鍵碼的前綴使用ORDER BY或GROUP BY SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3
在全部用在查詢中的列是鍵碼的一部分時間 SELECT key_part3 FROM table_name WHERE key_part1=1
--------------------------------------------------------------------------------
二十3、MySQL什麼時候不使用索引
若是MySQL能估計出它將可能比掃描整張表還要快時,則不使用索引。例如若是key_part1均勻分佈在1和100之間,下列查詢中使用索引就不是很好: SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90
若是使用HEAP表且不用=搜索全部鍵碼部分。
在HEAP表上使用ORDER BY。
若是不是用鍵碼第一部分 SELECT * FROM table_name WHERE key_part2=1
若是使用以一個通配符開始的LIKE SELECT * FROM table_name WHERE key_part1 LIKE '%jani%'
搜索一個索引而在另外一個索引上作ORDER BY SELECT * from table_name WHERE key_part1 = # ORDER BY key2
--------------------------------------------------------------------------------
二十4、學會使用EXPLAIN
對於每一條你認爲太慢的查詢使用EXPLAIN!
mysql> explain select t3.DateOfAction, t1.TransactionID -> from t1 join t2 join t3 -> where t2.ID = t1.TransactionID and t3.ID = t2.GroupID -> order by t3.DateOfAction, t1.TransactionID; +-------+--------+---------------+---------+---------+------------------+------+---------------------------------+ | table | type | possible_keys | key | key_len | ref | rows | Extra | +-------+--------+---------------+---------+---------+------------------+------+---------------------------------+ | t1 | ALL | NULL | NULL | NULL | NULL | 11 | Using temporary; Using filesort | | t2 | ref | ID | ID | 4 | t1.TransactionID | 13 | | | t3 | eq_ref | PRIMARY | PRIMARY | 4 | t2.GroupID | 1 | | +-------+--------+---------------+---------+---------+------------------+------+---------------------------------+
ALL和範圍類型提示一個潛在的問題。
--------------------------------------------------------------------------------
二十5、學會使用SHOW PROCESSLIST
使用SHOW processlist來發現正在作什麼: +----+-------+-----------+----+---------+------+--------------+-------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------+-----------+----+---------+------+--------------+-------------------------------------+ | 6 | monty | localhost | bp | Query | 15 | Sending data | select * from station,station as s1 | | 8 | monty | localhost | | Query | 0 | | show processlist | +----+-------+-----------+----+---------+------+--------------+-------------------------------------+
在mysql或mysqladmin中用KILL來殺死溜掉的線程。 --------------------------------------------------------------------------------
二十6、如何知曉MySQL解決一條查詢
運行項列命令並試圖弄明白其輸出: SHOW VARIABLES; SHOW COLUMNS FROM ...\G EXPLAIN SELECT ...\G FLUSH STATUS; SELECT ...; SHOW STATUS;
--------------------------------------------------------------------------------
二十7、MySQL很是不錯
日誌 在進行不少鏈接時,鏈接很是快。 同時使用SELECT和INSERT的場合。 在不把更新與耗時太長的選擇結合時。 在大多數選擇/更新使用惟一鍵碼時。 在使用沒有長時間衝突鎖定的多個表時。 在用大表時(MySQL使用一個很是緊湊的表格式)。
--------------------------------------------------------------------------------
二十8、MySQL應避免的事情
用刪掉的行更新或插入表,結合要耗時長的SELECT。 在能放在WHERE子句中的列上用HAVING。 不使用鍵碼或鍵碼不夠惟一而進行JOIN。 在不一樣列類型的列上JOIN。 在不使用=匹配整個鍵碼時使用HEAP表。 在MySQL監控程序中忘記在UPDATE或DELETE中使用一條WHERE子句。若是想這樣作,使用mysql客戶程序的--i-am-a-dummy選項。
--------------------------------------------------------------------------------
二十9、MySQL各類鎖定
內部表鎖定 LOCK TABLES(全部表類型適用) GET LOCK()/RELEASE LOCK() 頁面鎖定(對BDB表) ALTER TABLE也在BDB表上進行表鎖定 LOCK TABLES容許一個表有多個讀者和一個寫者。 通常WHERE鎖定具備比READ鎖定高的優先級以免讓寫入方乾等。對於不重要的寫入方,可使用LOW_PRIORITY關鍵字讓鎖定處理器優選讀取方。 UPDATE LOW_PRIORITY SET value=10 WHERE id=10;
--------------------------------------------------------------------------------
三10、給MySQL更多信息以更好地解決問題的技巧
注意你總能去掉(加註釋)MySQL功能以使查詢可移植:
SELECT /*! SQL_BUFFER_RESULTS */ ... SELECT SQL_BUFFER_RESULTS ... 將強制MySQL生成一個臨時結果集。只要全部臨時結果集生成後,全部表上的鎖定均被釋放。這能在遇到表鎖定問題時或要花很長時間將結果傳給客戶端時有所幫助。 SELECT SQL_SMALL_RESULT ... GROUP BY ... 告訴優化器結果集將只包含不多的行。 SELECT SQL_BIG_RESULT ... GROUP BY ... 告訴優化器結果集將包含不少行。 SELECT STRAIGHT_JOIN ... 強制優化器以出如今FROM子句中的次序聯結表。 SELECT ... FROM table_name [USE INDEX (index_list) | IGNORE INDEX (index_list)] table_name2 強制MySQL使用/忽略列出的索引。
--------------------------------------------------------------------------------
三11、事務的例子
MyIASM表如何進行事務處理: mysql> LOCK TABLES trans READ, customer WRITE; mysql> select sum(value) from trans where customer_id=some_id; mysql> update customer set total_value=sum_from_previous_statement where customer_id=some_id; mysql> UNLOCK TABLES;
BDB表如何進行事務: mysql> BEGIN WORK; mysql> select sum(value) from trans where customer_id=some_id; mysql> update customer set total_value=sum_from_previous_statement where customer_id=some_id; mysql> COMMIT;
注意你能夠經過下列語句迴避事務: UPDATE customer SET value=value+new_value WHERE customer_id=some_id;
--------------------------------------------------------------------------------
三12、使用REPLACE的例子
REPLACE的功能極像INSERT,除了若是一條老記錄在一個惟一索引上具備與新紀錄相同的值,那麼老記錄在新紀錄插入前則被刪除。不使用
SELECT 1 FROM t1 WHERE key=# IF found-row LOCK TABLES t1 DELETE FROM t1 WHERE key1=# INSERT INTO t1 VALUES (...) UNLOCK TABLES t1; ENDIF
而用 REPLACE INTO t1 VALUES (...)
--------------------------------------------------------------------------------
三十3、通常技巧
使用短主鍵。聯結表時使用數字而非字符串。 當使用多部分鍵碼時,第一部分應該時最經常使用的部分。 有疑問時,首先使用更多重複的列以得到更好地鍵碼壓縮。 若是在同一臺機器上運行MySQL客戶和服務器,那麼在鏈接MySQL時則使用套接字而不是TCP/IP(這能夠提升性能7.5%)。可在鏈接MySQL服務器時不指定主機名或主機名爲localhost來作到。 若是可能,使用--skip-locking(在某些OS上爲默認),這將關閉外部鎖定並將提升性能。 使用應用層哈希值而非長鍵碼: SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2)) AND col_1='constant' AND col_2='constant'
在文件中保存須要以文件形式訪問的BLOB,在數據庫中只保存文件名。 刪除全部行比刪除一大部分行要快。 若是SQL不夠快,研究一下訪問數據的較底層接口。
--------------------------------------------------------------------------------
三十4、使用MySQL 3.23的好處
MyISAM:可移植的大表格式 HEAP:內存中的表 Berkeley DB:支持事務的表。 衆多提升的限制 動態字符集 更多的STATUS變量 CHECK和REPAIR表 更快的GROUP BY和DISTINCT LEFT JOIN ... IF NULL的優化 CREATE TABLE ... SELECT CREATE TEMPORARY table_name (...) 臨時HEAP表到MyISAM表的自動轉換 複製 mysqlhotcopy腳本
--------------------------------------------------------------------------------
三十5、正在積極開發的重要功能
改進事務處理 失敗安全的複製 正文搜索 多個表的刪除(以後完成多個表的更新) 更好的鍵碼緩存 原子RENAME (RENAME TABLE foo as foo_old, foo_new as foo) 查詢高速緩存 MERGE TABLES 一個更好的GUI客戶程序
MySQL優化簡明指南
--------------------------------------------------------------------------------
2004-05-25
1、在編譯時優化MySQL 若是你從源代碼分發安裝MySQL,要注意,編譯過程對之後的目標程序性能有重要的影響,不一樣的編譯方式可能獲得相似的目標文件,但性能可能相差很大,所以,在編譯安裝MySQL適應仔細根據你的應用類型選擇最可能好的編譯選項。這種定製的MySQL能夠爲你的應用提供最佳性能。
技巧:選用較好的編譯器和較好的編譯器選項,這樣應用可提升性能10-30%。(MySQL文檔如是說)
1.一、使用pgcc(Pentium GCC)編譯器 該編譯器(http://www.goof.com/pcg/)針對運行?...繼諳低成杓頻摹?
1.二、僅使用你想使用的字符集編譯MySQL MySQL目前提供多達24種不一樣的字符集,爲全球用戶以他們本身的語言插入或查看錶中的數據。卻省狀況下,MySQL安裝全部者這些字符集,熱然而,最好的選擇是指選擇一種你須要的。如,禁止除Latin1字符集之外的全部其它字符集:
-------------------------------------------------------------------------------- %>./configure -with-extra-charsets=none [--other-configuration-options] --------------------------------------------------------------------------------
1.三、將mysqld編譯成靜態執行文件 將mysqld編譯成靜態執行文件而無需共享庫也能得到更好的性能。經過在配置時指定下列選項,可靜態編譯mysqld。
-------------------------------------------------------------------------------- %>./configure -with-mysqld-ldflags=-all-static [--other-configuration-options] --------------------------------------------------------------------------------
1.四、配置樣本 下列配置命令經常使用於提升性能:
-------------------------------------------------------------------------------- %>CFLAGS="-O6 -mpentiumpro -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --------------------------------------------------------------------------------
2、調整服務器 確保運用正確的編譯當然重要,但這只是成功的第一步,配置衆多的MySQL變量一樣對服務器的正常運行起關鍵做用。你能夠將這些變量的賦值存在一個配置文件中,以確保它們在每次啓動MySQL時均起做用,這個配置文件就是my.cnf文件。
MySQL已經提供了幾個my.cnf文件的樣本,可在/usr/local/mysqld/share/mysql/目錄下找到。這些文件分別命名爲 my-small.cnf、 my-medium.cnf、my-large.cnf和my-huge.cnf,規模說明可在描述配置文件適用的系統類型標題中找到。若是在只有至關少內存的系統上運行MySQL,並且只是偶爾的用一下,那麼my-small.cnf會比較理想,由於它命令mysqld只使用最少的資源。相似地,若是你計劃構建電子商務超市,並且系統擁有2G內存,那麼你可能要用到mysql-huge.cnf文件了。
爲了利用這些文件中的一個,你須要複製一個最適合需求的文件,更名爲my.cnf。你能夠選擇使用配置文件三種做用範圍的一種:
Global:將my.cnf文件複製到服務器的/etc目錄下,這使得配置文件中的變量做用於全局,即對全部服務器上的MySQL數據庫服務器有效。 Local:將my.cnf文件複製到[MYSQL-INSTALL-DIR]/var/目錄下,使得my.cnf做用於特定的服務器。[MYSQL-INSTALL-DIR]表示MySQL安裝目錄。 User:你能夠再限制做用於特定的用戶,將my.cnf複製到用戶的根目錄下。 究竟如何設置my.cnf中的這些變量呢?更進一步說,你能夠設置哪個變量。雖然所用變量對MySQL服務器相對通用,每個變量與MySQL的的某些組件有更特定的關係。如變量max_connects歸在mysqld類別下。執行下列命令便可知道:
-------------------------------------------------------------------------------- %>/usr/local/mysql/libexec/mysqld --help --------------------------------------------------------------------------------
它顯示大量的選項及與mysqld相關的變量。你能夠很容易地在該行文字之下找出變量:
-------------------------------------------------------------------------------- Possible variables for option --set-variable (-O) are --------------------------------------------------------------------------------
而後你能夠以下設置my.cnf中的那些變量:
-------------------------------------------------------------------------------- set-variable = max_connections=100 --------------------------------------------------------------------------------
它設置MySQL服務器的最大併發鏈接數爲100。要確保在my.cnf文件中的[mysqld]標題下插入變量設置。 3、表類型
不少MySQL用戶可能很驚訝,MySQL確實爲用戶提供5種不一樣的表類型,稱爲DBD、HEAP、ISAM、MERGE和MyIASM。DBD歸爲事務安全類,而其餘爲非事務安全類。
3.一、事務安全
DBD Berkeley DB(DBD)表是支持事務處理的表,由Sleepycat軟件公司(http://www.sleepycat.com)開發。它提供MySQL用戶期待已久的功能-事務控制。事務控制在任何數據庫系統中都是一個極有價值的功能,由於它們確保一組命令能成功地執行。
3.二、非事務安全
HEAP
HEAP表是MySQL中存取數據最快的表。這是由於他們使用存儲在動態內存中的一個哈希索引。另外一個要點是若是MySQL或服務器崩潰,數據將丟失。
ISAM
ISAM表是早期MySQL版本的缺省表類型,直到MyIASM開發出來。建議不要再使用它。
MERGE
MERGE是一個有趣的新類型,在3.23.25以後出現。一個MERGE表其實是一個相同MyISAM表的集合,合併成一個表,主要是爲了效率緣由。這樣能夠提升速度、搜索效率、修復效率並節省磁盤空間。
MyIASM
這是MySQL的缺省表類型。它基於IASM代碼,但有不少有用的擴展。MyIASM比較好的緣由:
MyIASM表小於IASM表,因此使用較少資源。 MyIASM表在不一樣的平臺上二進制層可移植。 更大的鍵碼尺寸,更大的鍵碼上限。 3.三、指定表類型
你可在建立表時指定表的類型。下例建立一個HEAP表:
--------------------------------------------------------------------------------
mysql>CREATE TABLE email_addresses TYPE=HEAP ( ->email char(55) NOT NULL, ->name char(30) NOT NULL, ->PRIMARY KEY(email) );
--------------------------------------------------------------------------------
BDB表須要一些配置工做,參見http://www.mysql.com/doc/B/D/BDB_overview.html。
3.四、更多的表類型
爲了使MySQL管理工做更有趣,即將發佈的MySQL 4.0將提供兩種新的表類型,稱爲Innobase和Gemeni。
四、優化工具
MySQL服務器自己提供了幾條內置命令用於幫助優化。
4.一、SHOW
你可能有興趣知道MySQL服務器究竟更了什麼,下列命令給出一個總結:
-------------------------------------------------------------------------------- mysql>show status; --------------------------------------------------------------------------------
它給出了一個至關長的狀態變量及其值的列表。有些變量包含了異常終止客戶的數量、異常終止鏈接的數量、鏈接嘗試的次數、最大併發鏈接數和大量其餘有用的信息。這些信息對找出系統問題和低效極具價值。 SHOW還能作更多的事情。它能夠顯示關於日誌文件、特定數據庫、表、索引、進程和權限表中有價值的信息。詳見MySQL手冊。
4.二、EXPLAIN
當你面對SELECT語句時,EXPLAIN解釋SELECT命令如何被處理。這不只對決定是否應該增長一個索引,並且對決定一個複雜的Join如何被MySQL處理都是有幫助的。
4.三、OPTIMIZE
OPTIMIZE語句容許你恢復空間和合並數據文件碎片,對包含變長行的表進行了大量更新和刪除後,這樣作特別重要。OPTIMIZE目前只工做於MyIASM和BDB表。