1. 程式人生 > >Mysql資料庫的優化(主Sql優化)

Mysql資料庫的優化(主Sql優化)

1. 目標

l 瞭解什麼是優化

l 掌握優化查詢的方法

l 掌握優化資料庫結構的方法

l 掌握優化MySQL伺服器的方法

2. 什麼是優化?

l 合理安排資源、調整系統引數使MySQL執行更快、更節省資源。

l 優化是多方面的,包括查詢、更新、伺服器等。

原則:減少系統瓶頸,減少資源佔用,增加系統的反應速度。

3. 資料庫效能引數

l 使用SHOW STATUS語句檢視MySQL資料庫的效能引數

• SHOW STATUS LIKE 'value‘

l 常用的引數:

• Slow_queries  慢查詢次數

• Com_(CRUD) 操作的次數

• Uptime  上線時間

4. 查詢優化

4.1. EXPLAIN

MySQL中可以使用EXPLAIN檢視SQL執行計劃,用法:EXPLAIN SELECT * FROM tb_item

 

4.2. 結果說明

4.2.1. id

SELECT識別符。這是SELECT查詢序列號。這個不重要。

4.2.2. select_type

表示SELECT語句的型別

有以下幾種值

1、 SIMPLE
表示簡單查詢其中不包含連線查詢和子查詢

2、 PRIMARY
表示主查詢或者是最外面的查詢語句


3、 UNION
表示連線查詢的第2個或後面的查詢語句。


4、 DEPENDENT UNION
UNION中的第二個或後面的SELECT語句,取決於外面的查詢。

5、 UNION RESULT
連線查詢的結果

6、 SUBQUERY
子查詢中的第1SELECT語句。


7、 DEPENDENT SUBQUERY
子查詢中的第

1SELECT語句,取決於外面的查詢。

8、 DERIVED
SELECT(FROM 子句的子查詢)

4.2.3. table

表示查詢的表

4.2.4. type(重要)

表示表的連線型別

以下的連線型別的順序是從最佳型別到最差型別


1、 system
表僅有一行,這是const型別的特列,平時不會出現,這個也可以忽略不計。

2、 const
資料表最多隻有一個匹配行,因為只匹配一行資料,所以很快,常用於PRIMARY KEY或者UNIQUE索引的查詢,可理解為const是最優化的


3、 eq_ref
mysql手冊是這樣說的:"對於每個來自於前面的表的行組合,從該表中讀取一行。這可能是最好的聯接型別,除了const型別。它用在一個索引的所有部分被聯接使用並且索引是UNIQUEPRIMARY KEY"eq_ref可以用於使用=比較帶索引的列。


4、 ref
查詢條件索引既不是UNIQUE也不是PRIMARY KEY的情況ref可用於=<>操作符的帶索引的列。


5、 ref_or_null
該聯接型別如同ref,但是添加了MySQL可以專門搜尋包含NULL值的行。在解決子查詢中經常使用該聯接型別的優化。

 

上面這五種情況都是很理想的索引使用情況。

6、 index_merge
該聯接型別表示使用了索引合併優化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關鍵元素。

7、 unique_subquery
該型別替換了下面形式的IN子查詢的ref: value IN (SELECT primary_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、 range
只檢索給定範圍的行,使用一個索引來選擇行。


10、 index
該聯接型別與ALL相同,除了只有索引樹被掃描。這通常比ALL,因為索引檔案通常比資料檔案小。

11、 ALL
對於每個來自於先前的表的行組合,進行完整的表掃描。(效能最差

4.2.5. possible_keys

指出MySQL能使用哪個索引在該表中找到行。

如果該列為NULL,說明沒有使用索引可以對該列建立索引來提高效能

4.2.6. key

顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL

 

可以強制使用索引或者忽略索引


 

4.2.7. key_len

顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL

注意:key_len是確定了MySQL將實際使用的索引長度

4.2.8. ref

顯示使用哪個列或常數與key一起從表中選擇行。

4.2.9. rows

顯示MySQL認為它執行查詢時必須檢查的行數。

4.2.10. Extra

該列包含MySQL解決查詢的詳細資訊

· Distinct:MySQL發現第1個匹配行後,停止為當前的行組合搜尋更多的行。

· 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 BYDISTINCT查詢的所有列,而不要額外搜尋硬碟訪問實際的表。

4.3. 使用索引查詢需要注意

索引可以提供查詢的速度但並不是使用了帶有索引的欄位查詢都會生效有些情況下是不生效的需要注意

4.3.1. 使用LIKE關鍵字的查詢

在使用LIKE關鍵字進行查詢的查詢語句中如果匹配字串的第一個字元為%”,索引不起作用只有%”不在第一個位置,索引才會生效

 

 

 

4.3.2. 使用聯合索引的查詢

MySQL可以為多個欄位建立索引一個索引可以包括16個欄位。對於聯合索引,只有查詢條件中使用了這些欄位中第一個欄位時,索引才會生效。

 

 


 

4.3.3. 使用OR關鍵字的查詢

查詢語句的查詢條件中只有OR關鍵字OR前後的兩個條件中的列都是索引時索引才會生效否則索引不生效

 

 



4.4. 子查詢優化

MySQL4.1版本開始支援子查詢,使用子查詢進行SELECT語句巢狀查詢,可以一次完成很多邏輯上需要多個步驟才能完成的SQL操作。

 

子查詢雖然很靈活但是執行效率並不高

 

執行子查詢時,MYSQL需要建立臨時表查詢完畢後再刪除這些臨時表所以子查詢的速度會受到一定的影響

 

優化:

可以使用連線查詢JOIN代替子查詢連線查詢時不需要建立臨時表其速度比子查詢快

5. 資料庫結構優化

一個好的資料庫設計方案對於資料庫的效能往往會起到事半功倍的效果

 

需要考慮資料冗餘、查詢和更新的速度、欄位的資料型別是否合理等多方面的內容。

5.1. 將欄位很多的表分解成多個表

對於欄位較多的表如果有些欄位的使用頻率很低可以將這些欄位分離出來形成新表

 

因為當一個表的資料量很大時會由於使用頻率低的欄位的存在而變慢

 

5.2. 增加中間表

對於需要經常聯合查詢的表可以建立中間表以提高查詢效率

 

通過建立中間表將需要通過聯合查詢的資料插入到中間表中然後將原來的聯合查詢改為對中間表的查詢

5.3. 增加冗餘欄位

設計資料表時應儘量遵循正規化理論的規約儘可能的減少冗餘欄位讓資料庫設計看起來精緻、優雅。但是,合理的加入冗餘欄位可以提高查詢速度。

 

表的規範化程度越高表和表之間的關係越多需要連線查詢的情況也就越多效能也就越差

 

注意:

冗餘欄位的值在一個表中修改了就要想辦法在其他表中更新否則就會導致資料不一致的問題。

6. 插入資料的優化

插入資料時影響插入速度的主要是索引唯一性校驗一次插入的資料條數等

 

插入資料的優化不同的儲存引擎優化手段不一樣,在MySQL常用的儲存引擎有,MyISAMInnoDB兩者的區別

 

http://www.cnblogs.com/panfeng412/archive/2011/08/16/2140364.html

 

6.1. MyISAM

6.1.1. 禁用索引

對於非空表插入記錄時,MySQL會根據表的索引對插入的記錄建立索引如果插入大量資料建立索引會降低插入資料速度

 

為了解決這個問題可以在批量插入資料之前禁用索引資料插入完成後再開啟索引

 

禁用索引的語句

ALTER TABLE table_name DISABLE KEYS

 

開啟索引語句

ALTER TABLE table_name ENABLE KEYS

 

對於空表批量插入資料則不需要進行操作因為MyISAM引擎的表是在匯入資料後才建立索引

6.1.2. 禁用唯一性檢查

唯一性校驗會降低插入記錄的速度可以在插入記錄之前禁用唯一性檢查插入資料完成後再開啟

 

禁用唯一性檢查的語句SET UNIQUE_CHECKS = 0;

 

開啟唯一性檢查的語句:SET UNIQUE_CHECKS = 1;

6.1.3. 批量插入資料

插入資料時可以使用一條INSERT語句插入一條資料也可以插入多條資料

 


 

第二種方式的插入速度比第一種方式快

6.1.4. 使用LOAD DATA INFILE

當需要批量匯入資料時,使用LOAD DATA INFILE語句INSERT語句插入速度快很多。

6.2. InnoDB

6.2.1. 禁用唯一性檢查

用法和MyISAM一樣

6.2.2. 禁用外來鍵檢查

插入資料之前執行禁止對外來鍵的檢查資料插入完成後再恢復,可以提供插入速度。

 

禁用:SET foreign_key_checks = 0;

開啟:SET foreign_key_checks = 1;

6.2.3. 禁止自動提交

插入資料之前執行禁止事務的自動提交資料插入完成後再恢復,可以提高插入速度。

 

禁用:SET autocommit = 0;

開啟:SET autocommit = 1;

7. 伺服器優化

7.1. 優化伺服器硬體

伺服器的硬體效能直接決定著MySQL資料庫的效能硬體的效能瓶頸直接決定MySQL資料庫的執行速度和效率

 

需要從以下幾個方面考慮

1、 配置較大的記憶體。足夠大的記憶體,是提高MySQL資料庫效能的方法之一。記憶體的IO比硬碟快的多,可以增加系統的緩衝區容量,使資料在記憶體停留的時間更長,以減少磁碟的IO

2、 配置高速磁碟,比如SSD

3、 合理分配磁碟IO,把磁碟IO分散到多個裝置上以減少資源的競爭提高並行操作能力

4、 配置多核處理器,MySQL是多執行緒的資料庫多處理器可以提高同時執行多個執行緒的能力

7.2. 優化MySQL的引數

通過優化MySQL的引數可以提高資源利用率從而達到提高MySQL伺服器效能的目的

 

MySQL的配置引數都在my.conf或者my.ini檔案的[mysqld]組中,常用的引數如下:

 

 

要求必須記憶至少3個。