<script> var $tag='mysql,雜談'; </script> | 分類:mysql |
1. 選擇合適的數據引擎
MyISAM:適用於大量的讀操作的表
InnoDB:適用於大量的寫讀作的表
2.選擇合適的列類型
使用 SELECT * FROM TB_TEST PROCEDURE ANALYSE()可以對這個表的每一個字段進行分析,給出優化列類型建議
(八)建立索引原則
1.合理使用索引
一個Table在一次query中只能使用一個索引,使用EXPLAIN語句來檢驗優化程序的操作情況
使用analyze幫助優化程序對索引的使用效果做出更準確的預測
2.索引應該創建在搜索、排序、歸組等操作所涉及的數據列上
3.儘量將索引建立在重複數據少的數據列中,唯一所以最好
例如:生日列,可以建立索引,但性別列不要建立索引
4.儘量對比較短的值進行索引
降低磁盤IO操作,索引緩衝區中可以容納更多的鍵值,提高命中率
如果對一個長的字符串建立索引,可以指定一個前綴長度
5.合理使用多列索引
如果多個條件經常需要組合起來查詢,則要使用多列索引(因爲一個表一次查詢只能使用一個索引,建立多個單列索引也只能使用一個)
6.充分利用最左前綴
也就是要合理安排多列索引中各列的順序,將最常用的排在前面
7.不要建立過多的索引
只有經常應用於where,order by,group by中的字段需要建立索引.
8.利用慢查詢日誌查找出慢查詢(log-slow-queries, long_query_time)
(九)充分利用索引
1.儘量比較數據類型相同的數據列
3.儘可能不對查詢字段加函數,
如WHERE YEAR(date_col) < 1990改造成WHERE date_col < ’1990-01-01’
WHERE TO_DAYS(date_col) - TO_DAYS(CURDATE()) < cutoff 改造成WHERE date_col < DATE_ADD(CURDATE(), INTERVAL cutoff DAY)
(十)SQL語句的優化
1.創建合適的統計中間結果表,降低從大表查詢數據的機率
2.儘量避免使用子查詢,而改用連接的方式.例如:
SELECT a.id, (SELECT MAX(created) FROM posts WHERE author_id = a.id) AS latest_post
FROM authors a
可以改成:
SELECT a.id, MAX(p.created) AS latest_post
FROM authors AS a
INNER JOIN posts p ON (a.id = p.author_id)
GROUP BY a.id
select song_id from song_lib where singer_id in
(select singer_id from singer_lib
where first_char='A'
) limit 2000改成:
select song_id from song_lib a
inner join singer_lib b on a.singer_id=b.singer_id and first_char='A' limit 2000
3.插入判斷重複鍵時,使用ON DUPLICATE KEY UPDATE :
insert into db_action.action_today(user_id,song_id,action_count) values(1,1,1) ON DUPLICATE KEY UPDATE action_count=action_count+1;
4.避免使用遊標
遊標的運行效率極低,可以通過增加臨時表,運用多表查詢,多表更新等方式完成任務,不要使用遊標.
(十一)使用Explain分析SQL語句使用索引的情況
當你在一條SELECT語句前放上關鍵詞EXPLAIN,MySQL解釋它將如何處理SELECT,提供有關表如何聯結和以什麼次序聯結的信息,藉助於EXPLAIN,可以知道什麼時候必須爲表加入索引以得到一個使用索引來尋找記錄的更快的SELECT,你也能知道優化器是否以一個最佳次序聯結表。爲了強制優化器對一個SELECT語句使用一個特定聯結次序,增加一個STRAIGHT_JOIN子句。。
EXPLAIN命令的一般語法是:EXPLAIN <SQL命令> 如:explain select * from a inner join b on a.id=b.id
EXPLAIN的分析結果參數詳解:
1.table:這是表的名字。
2.type:連接操作的類型。
system:表中僅有一條記錄(實際應用很少只有一條資料的表)
const:表最多有一個匹配行,用於用常數值比較PRIMARY KEY或UNIQUE索引的所有部分時,
如:select * from song_lib where song_id=2(song_id爲表的primary key)
eq_ref:對於每個來自於前面的表的行組合,從該表中用UNIQUE或PRIMARY KEY的索引讀取一行,
如:select * from song_lib a inner join singer_lib b on a.singer_id=b.singer_id(b的type值爲eq_ref)
ref:對於每個來自於前面的表的行組合,從該表中用非UNIQUE或PRIMARY KEY的索引讀取一行
如:select * from song_lib a inner join singer_lib b on a.singer_name=b.singer_name和
select * from singer_lib b where singer_name=‘ccc’ (b的type值爲ref,因爲b.singer_name是普通索引)
ref_or_null:該聯接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行,
如:select * from singer_lib where singer_name=‘ccc’ or singer_name is null
index_merge:該聯接類型表示使用了索引合併優化方法
Key:它顯示了MySQL實際使用的索引的名字。如果它爲空(或NULL),則MySQL不使用索引。
key_len:索引中被使用部分的長度,以字節計。
3.ref:ref列顯示使用哪個列或常數與key一起從表中選擇行
4.rows: MySQL所認爲的它在找到正確的結果之前必須掃描的記錄數。顯然,這裏最理想的數字就是1。
5.Extra:這裏可能出現許多不同的選項,其中大多數將對查詢產生負面影響。一般有:
using where:表示使用了where條件
using filesort: 表示使用了文件排序,也就是使用了order by子句,並且沒有用到order by 裏字段的索引,從而需要
額外的排序開銷,所以如果出現using filesort就表示排序的效率很低,需要進行優化,比如採用強制索引
的方法(force index)