MySQL的優(yōu)化2
發(fā)布時(shí)間:2008-08-13 閱讀數(shù): 次 來源:網(wǎng)樂原科技
二十六、如何知曉MySQL解決一條查詢
運(yùn)行項(xiàng)列命令并試圖弄明白其輸出:
SHOW VARIABLES;
SHOW COLUMNS FROM ...\G
EXPLAIN SELECT ...\G
FLUSH STATUS;
SELECT ...;
SHOW STATUS;
--------------------------------------------------------------------------------
二十七、MySQL非常不錯
日志
在進(jìn)行很多連接時(shí),連接非常快。
同時(shí)使用SELECT和INSERT的場合。
在不把更新與耗時(shí)太長的選擇結(jié)合時(shí)。
在大多數(shù)選擇/更新使用唯一鍵碼時(shí)。
在使用沒有長時(shí)間沖突鎖定的多個表時(shí)。
在用大表時(shí)(MySQL使用一個非常緊湊的表格式)。
--------------------------------------------------------------------------------
二十八、MySQL應(yīng)避免的事情
用刪掉的行更新或插入表,結(jié)合要耗時(shí)長的SELECT。
在能放在WHERE子句中的列上用HAVING。
不使用鍵碼或鍵碼不夠唯一而進(jìn)行JOIN。
在不同列類型的列上JOIN。
在不使用=匹配整個鍵碼時(shí)使用HEAP表。
在MySQL監(jiān)控程序中忘記在UPDATE或DELETE中使用一條WHERE子句。如果想這樣做,使用mysql客戶程序的--i-am-a-dummy選項(xiàng)。
--------------------------------------------------------------------------------
二十九、MySQL各種鎖定
內(nèi)部表鎖定
LOCK TABLES(所有表類型適用)
GET LOCK()/RELEASE LOCK()
頁面鎖定(對BDB表)
ALTER TABLE也在BDB表上進(jìn)行表鎖定
LOCK TABLES允許一個表有多個讀者和一個寫者。
一般WHERE鎖定具有比READ鎖定高的優(yōu)先級以避免讓寫入方干等。對于不重要的寫入方,可以使用LOW_PRIORITY關(guān)鍵字讓鎖定處理器優(yōu)選讀取方。
UPDATE LOW_PRIORITY SET value=10 WHERE id=10;
--------------------------------------------------------------------------------
三十、給MySQL更多信息以更好地解決問題的技巧
注意你總能去掉(加注釋)MySQL功能以使查詢可移植:
SELECT /*! SQL_BUFFER_RESULTS */ ...
SELECT SQL_BUFFER_RESULTS ...
將強(qiáng)制MySQL生成一個臨時(shí)結(jié)果集。只要所有臨時(shí)結(jié)果集生成后,所有表上的鎖定均被釋放。這能在遇到表鎖定問題時(shí)或要花很長時(shí)間將結(jié)果傳給客戶端時(shí)有所幫助。
SELECT SQL_SMALL_RESULT ... GROUP BY ...
告訴優(yōu)化器結(jié)果集將只包含很少的行。
SELECT SQL_BIG_RESULT ... GROUP BY ...
告訴優(yōu)化器結(jié)果集將包含很多行。
SELECT STRAIGHT_JOIN ...
強(qiáng)制優(yōu)化器以出現(xiàn)在FROM子句中的次序聯(lián)結(jié)表。
SELECT ... FROM table_name [USE INDEX (index_list) | IGNORE INDEX (index_list)] table_name2
強(qiáng)制MySQL使用/忽略列出的索引。
--------------------------------------------------------------------------------
三十一、事務(wù)的例子
MyIASM表如何進(jìn)行事務(wù)處理:
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表如何進(jìn)行事務(wù):
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;
注意你可以通過下列語句回避事務(wù):
UPDATE customer SET value=value+new_value WHERE customer_id=some_id;
--------------------------------------------------------------------------------
三十二、使用REPLACE的例子
REPLACE的功能極像INSERT,除了如果一條老記錄在一個唯一索引上具有與新紀(jì)錄相同的值,那么老記錄在新紀(jì)錄插入前則被刪除。不使用
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 (...)
--------------------------------------------------------------------------------
三十三、一般技巧
使用短主鍵。聯(lián)結(jié)表時(shí)使用數(shù)字而非字符串。
當(dāng)使用多部分鍵碼時(shí),第一部分應(yīng)該時(shí)最常用的部分。
有疑問時(shí),首先使用更多重復(fù)的列以獲得更好地鍵碼壓縮。
如果在同一臺機(jī)器上運(yùn)行MySQL客戶和服務(wù)器,那么在連接MySQL時(shí)則使用套接字而不是TCP/IP(這可以提高性能7.5%)。可在連接MySQL服務(wù)器時(shí)不指定主機(jī)名或主機(jī)名為localhost來做到。
如果可能,使用--skip-locking(在某些OS上為默認(rèn)),這將關(guān)閉外部鎖定并將提高性能。
使用應(yīng)用層哈希值而非長鍵碼:
SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2)) AND
col_1='constant' AND col_2='constant'
在文件中保存需要以文件形式訪問的BLOB,在數(shù)據(jù)庫中只保存文件名。
刪除所有行比刪除一大部分行要快。
如果SQL不夠快,研究一下訪問數(shù)據(jù)的較底層接口。
--------------------------------------------------------------------------------
三十四、使用MySQL 3.23的好處
MyISAM:可移植的大表格式
HEAP:內(nèi)存中的表
Berkeley DB:支持事務(wù)的表。
眾多提高的限制
動態(tài)字符集
更多的STATUS變量
CHECK和REPAIR表
更快的GROUP BY和DISTINCT
LEFT JOIN ... IF NULL的優(yōu)化
CREATE TABLE ... SELECT
CREATE TEMPORARY table_name (...)
臨時(shí)HEAP表到MyISAM表的自動轉(zhuǎn)換
復(fù)制
mysqlhotcopy腳本
--------------------------------------------------------------------------------
三十五、正在積極開發(fā)的重要功能
改進(jìn)事務(wù)處理
失敗安全的復(fù)制
正文搜索
多個表的刪除(之后完成多個表的更新)
更好的鍵碼緩存
原子RENAME (RENAME TABLE foo as foo_old, foo_new as foo)
查詢高速緩存
MERGE TABLES
一個更好的GUI客戶程序