作爲程序員,天天都要和數據庫打交道,而且以mysql居多,而數據庫的優化,也是一個老生常談的話題。今天我就整理一下mysql數據庫的優化方式。
開始:
首先是查詢優化:
一條查詢語句在數據庫中執行,如果該條語句的執行時間比較長,那麼就會被數據庫記錄爲慢查詢,那麼我們怎麼來查看我們寫的哪些語句是慢查詢的呢?我們可以在數據庫中查看mysql的性能參數。
查看mysql性能參數的命令:SHOW STATUS 可以查看,這裏有幾百條參數。。。
比如一條查詢sql超過我們制定的時間,會被記錄爲慢查詢,並記錄下這條sql制定查詢慢查詢的方式:
SHOW STATUS LIKE 'Slow_queries'
因爲我這裏沒有符合條件的,所以沒有值。你可以根據具體情況,到mysql的執行日誌中找到語句並進行語句的優化。
查看C/R/U/D的執行次數(只配一圖)
show status like 'Com_insert'
show status like 'Com_select'
show status like 'Com_update'
show status like 'Com_delete'
EXPLAIN 可以查看sql執行的過程,通過了解過程,我們進行相應的優化
EXPLAIN SELECT * FROM BOOK;
select_type:查詢的方式
1:SIMPLE 簡單的查詢,不包括連接查詢和子查詢
2:PRIMARY 表示主查詢,或者最外面的查詢
3:UNION 表示連接查詢,第二個或後面的查詢
4:DEPENDENT UNION 表示UNION中第二個或者後面的SELECT語句,取決於外面的查詢
5:UNION RESULT 表示連接查詢的結果
6:SUBQUERY 表示子查詢的第一個查詢語句
7:ENPENDENT SUBQUERY 表示子查詢的第一個查詢語句,取決於外面的查詢
8:DERIVED 表示SELECT(FROM 子句的子查詢)
而我們需要注意的是SUBQUERY,一旦出現這個,我們就要注意考慮對查詢進行優化了!!!
table:表示查詢的表
type:表示表的連接類型(重要)
從最佳類型到最差類型:
1:system 表示表僅有一行,這是const類型的特列,平時不會出現,可以忽略
2:const 表示數據表只有一個匹配行,因爲只匹配一行數據,所以很快,常用於PRIMARY KEY 或者 UNIQUE 的索引查詢,可以認爲const是最優的3:eq_ref mysql手冊是這樣說的:對於每個來自前面的表的行組合,從該表中讀取一行,這可能是最好的連接類型,除了const。它用在一個索引的所有部分被連接使用並且索引時UNIQUE 或 PRIMARY KEY ,eq_ref 可以用於使用 =帶索引的列。
4:ref 查詢條件索引既不是UNIQUE 也不是 PRIMARY KEY 的情況,ref可以用於 =或<或>操作符的帶索引的列
5:ref_or_null 該連接類型如同ref,但是添加了mysql可以專門搜索包含null值得行,在解決子查詢中常使用該類型的優化。
以上5條都是可以接收的,下面的情況就需要我們考慮去優化了
6:index_merge 該連接類型表示使用了索引合併優化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關鍵元素。
7:unique_subquery 該類型替換了下面的形式的in子查詢的ref: value in(select primery_key from single_table where some_expr),unique_subquery 是一個索引查詢函數,可以完全替換子查詢,效率更高
8:index_subquery 該連接類型類似於unique_subquery。可以替換in子查詢,但是隻適合下列形式的子查詢中的非唯一索引:value in(select key_column from single_table where some_expr)
9:renge 只檢索給定範圍的行,使用一個索引來擇行。
10:index 該連接類型與ALL相同,除了只有索引樹被掃描。這通常比All塊,因爲索引文件通常比數據文件小。
11:All 對於每個來自於先前的表的行組合,進行完整的表掃描。(性能最差)
possible_keys
指出mysql能使用哪個索引在該表中找到行。
如果該列爲null,說明沒有使用索引,可以對該列長江索引來提高性能。
key
顯示mysql實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是null。
可以強制使用索引或者忽略索引:
key_len
顯示mysql決定使用的鍵的長度,如果鍵是null,則長度爲null
注意:key_len 是確定了mysql將實際使用的索引長度。
ref
顯示使用哪個列域或常數與key儀器從表中選擇行。
rows
顯示mysql認爲它執行查詢時必須檢查的行數。
Extra
該列包含mysql解決查詢的詳細信息:
Distinct:mysql 發現第一個匹配行後,停止位當前的行組合搜索更多的行
Not exists:mysql 能夠對查詢進行LEFT JOIN 優化,發現1個匹配LEFT JOIN 標準的行後,不在爲前面的行組合在該表內檢查更多的行。
range checked for each record(index map:#) :mysql沒有發現好的可以使用的索引,單發現如果來自前面的表的列值已知,可能索引可以使用。
Using filesort:mysql需要額外的一次傳遞,以找出如何安排順序檢索行。
using index:從只使用索引樹種的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息。
Using temporary : 爲了解決查詢,mysql需要創建一個臨時表來容納結果。
Using where:where子語句用於限制哪一個行匹配下一個表或發送到客戶。
using sort_union(....),Using union(...),Using intersect(...)這些函數說明如何爲index——merge連接類型合併索引掃描。
Using index for group-by :類似於訪問表的Using index方式,using index for group-by 表示mysql發現一個索引,可以用來查詢group by 或 distinct 查詢的說有列,而不要額外搜索硬盤訪問實際的表。
使用索引查詢注意事項:
1.使用like 查詢時,第一個字符是%時,索引不生效
2.使用聯合索引查詢,mysql可以爲多個字段創建索引,一個索引可以包括16個字段,對於聯合索引,只有查詢條件中使用了這些字段中的第一個字段,索引才生效
3.使用or關鍵字的查詢,查詢語句中 只有or關鍵字,並且or的前後兩個條件中的列都是索引時 ,索引才生效。
子查詢優化
使用連接查詢(join)代替子查詢,連接查詢時不需要建立臨時表,速度更快。