l 瞭解什麼是優化mysql
l 掌握優化查詢的方法sql
l 掌握優化數據庫結構的方法數據庫
l 掌握優化MySQL服務器的方法服務器
l 合理安排資源、調整系統參數使MySQL運行更快、更節省資源。多線程
l 優化是多方面的,包括查詢、更新、服務器等。數據庫設計
l 原則:減小系統瓶頸,減小資源佔用,增長系統的反應速度。函數
l 使用SHOW STATUS語句查看MySQL數據庫的性能參數性能
l 經常使用的參數:優化
SHOW STATUS LIKE ‘Slow_queries‘spa
SHOW STATUS LIKE ‘Com_insert‘
SHOW STATUS LIKE ‘Com_delete‘
SHOW STATUS LIKE ‘Com_update‘
在MySQL中可使用EXPLAIN查看SQL執行計劃,用法:EXPLAIN SELECT * FROM tb_item
SELECT識別符。這是SELECT查詢序列號。這個不重要。
表示SELECT語句的類型。
有如下幾種值:
一、 SIMPLE
表示簡單查詢,其中不包含鏈接查詢和子查詢。
二、 PRIMARY
表示主查詢,或者是最外面的查詢語句。
三、 UNION
表示鏈接查詢的第2個或後面的查詢語句。
四、 DEPENDENT UNION
UNION中的第二個或後面的SELECT語句,取決於外面的查詢。
五、 UNION RESULT
鏈接查詢的結果。
六、 SUBQUERY
子查詢中的第1個SELECT語句。
七、 DEPENDENT SUBQUERY
子查詢中的第1個SELECT語句,取決於外面的查詢。
八、 DERIVED
SELECT(FROM 子句的子查詢)。
表示查詢的表。
表示表的鏈接類型。
如下的鏈接類型的順序是從最佳類型到最差類型:
一、 system
表僅有一行,這是const類型的特列,平時不會出現,這個也能夠忽略不計。
二、 const
數據表最多隻有一個匹配行,由於只匹配一行數據,因此很快,經常使用於PRIMARY KEY或者UNIQUE索引的查詢,可理解爲const是最優化的。
三、 eq_ref
mysql手冊是這樣說的:"對於每一個來自於前面的表的行組合,從該表中讀取一行。這多是最好的聯接類型,除了const類型。它用在一個索引的全部部分被聯接使用而且索引是UNIQUE或PRIMARY KEY"。eq_ref能夠用於使用=比較帶索引的列。
四、 ref
查詢條件索引既不是UNIQUE也不是PRIMARY KEY的狀況。ref可用於=或<或>操做符的帶索引的列。
五、 ref_or_null
該聯接類型如同ref,可是添加了MySQL能夠專門搜索包含NULL值的行。在解決子查詢中常用該聯接類型的優化。
上面這五種狀況都是很理想的索引使用狀況。
下面的必需要優化
六、 index_merge
該聯接類型表示使用了索引合併優化方法。在這種狀況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關鍵元素。
七、 unique_subquery
該類型替換了下面形式的IN子查詢的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一個索引查找函數,能夠徹底替換子查詢,效率更高。
八、 index_subquery
該聯接類型相似於unique_subquery。能夠替換IN子查詢,但只適合下列形式的子查詢中的非惟一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
九、 range
只檢索給定範圍的行,使用一個索引來選擇行。
十、 index
該聯接類型與ALL相同,除了只有索引樹被掃描。這一般比ALL快,由於索引文件一般比數據文件小。
十一、 ALL
對於每一個來自於先前的表的行組合,進行完整的表掃描。(性能最差)
指出MySQL能使用哪一個索引在該表中找到行。
若是該列爲NULL,說明沒有使用索引,能夠對該列建立索引來提升性能。
顯示MySQL實際決定使用的鍵(索引)。若是沒有選擇索引,鍵是NULL。
能夠強制使用索引或者忽略索引:
顯示MySQL決定使用的鍵長度。若是鍵是NULL,則長度爲NULL。
注意:key_len是肯定了MySQL將實際使用的索引長度。
顯示使用哪一個列或常數與key一塊兒從表中選擇行。
顯示MySQL認爲它執行查詢時必須檢查的行數。
該列包含MySQL解決查詢的詳細信息
索引能夠提供查詢的速度,但並非使用了帶有索引的字段查詢都會生效,有些狀況下是不生效的,須要注意!
在使用LIKE關鍵字進行查詢的查詢語句中,若是匹配字符串的第一個字符爲「%」,索引不起做用。只有「%」不在第一個位置,索引纔會生效。
MySQL能夠爲多個字段建立索引,一個索引能夠包括16個字段。對於聯合索引,只有查詢條件中使用了這些字段中第一個字段時,索引纔會生效。
以下表tb_cart中建表是聲明2個索引(聯合) 順序是user_id和item_id
查詢語句的查詢條件中只有OR關鍵字,且OR先後的兩個條件中的列都是索引時,索引纔會生效,不然,索引不生效。
MySQL從4.1版本開始支持子查詢,使用子查詢進行SELECT語句嵌套查詢,能夠一次完成不少邏輯上須要多個步驟才能完成的SQL操做。
子查詢雖然很靈活,可是執行效率並不高。
執行子查詢時,MYSQL須要建立臨時表,查詢完畢後再刪除這些臨時表,因此,子查詢的速度會受到必定的影響。
優化:
可使用鏈接查詢(JOIN)代替子查詢,鏈接查詢時不須要創建臨時表,其速度比子查詢快。
一個好的數據庫設計方案對於數據庫的性能每每會起到事半功倍的效果。
須要考慮數據冗餘、查詢和更新的速度、字段的數據類型是否合理等多方面的內容。
對於字段較多的表,若是有些字段的使用頻率很低,能夠將這些字段分離出來造成新表。
由於當一個表的數據量很大時,會因爲使用頻率低的字段的存在而變慢。
對於須要常常聯合查詢的表,能夠創建中間表以提升查詢效率。
經過創建中間表,將須要經過聯合查詢的數據插入到中間表中,而後將原來的聯合查詢改成對中間表的查詢。
設計數據表時應儘可能遵循範式理論的規約,儘量的減小冗餘字段,讓數據庫設計看起來精緻、優雅。可是,合理的加入冗餘字段能夠提升查詢速度。
表的規範化程度越高,表和表之間的關係越多,須要鏈接查詢的狀況也就越多,性能也就越差。
注意:
冗餘字段的值在一個表中修改了,就要想辦法在其餘表中更新,不然就會致使數據不一致的問題。
插入數據時,影響插入速度的主要是索引、惟一性校驗、一次插入的數據條數等。
插入數據的優化,不一樣的存儲引擎優化手段不同,在MySQL中經常使用的存儲引擎有,MyISAM和InnoDB,二者的區別:
對於非空表,插入記錄時,MySQL會根據表的索引對插入的記錄創建索引。若是插入大量數據,創建索引會下降插入數據速度。
爲了解決這個問題,能夠在批量插入數據以前禁用索引,數據插入完成後再開啓索引。
禁用索引的語句:
ALTER TABLE table_name DISABLE KEYS
開啓索引語句:
ALTER TABLE table_name ENABLE KEYS
對於空表批量插入數據,則不須要進行操做,由於MyISAM引擎的表是在導入數據後才創建索引。
惟一性校驗會下降插入記錄的速度,能夠在插入記錄以前禁用惟一性檢查,插入數據完成後再開啓。
禁用惟一性檢查的語句:SET UNIQUE_CHECKS = 0;
開啓惟一性檢查的語句:SET UNIQUE_CHECKS = 1;
插入數據時,可使用一條INSERT語句插入一條數據,也能夠插入多條數據。
第二種方式的插入速度比第一種方式快。
當須要批量導入數據時,使用LOAD DATA INFILE語句比INSERT語句插入速度快不少。
用法和MyISAM同樣。
插入數據以前執行禁止對外鍵的檢查,數據插入完成後再恢復,能夠提供插入速度。
禁用:SET foreign_key_checks = 0;
開啓:SET foreign_key_checks = 1;
插入數據以前執行禁止事務的自動提交,數據插入完成後再恢復,能夠提升插入速度。
禁用:SET autocommit = 0;
開啓:SET autocommit = 1;
服務器的硬件性能直接決定着MySQL數據庫的性能,硬件的性能瓶頸,直接決定MySQL數據庫的運行速度和效率。
須要從如下幾個方面考慮:
一、 配置較大的內存。足夠大的內存,是提升MySQL數據庫性能的方法之一。內存的IO比硬盤快的多,能夠增長系統的緩衝區容量,使數據在內存停留的時間更長,以減小磁盤的IO。
二、 配置高速磁盤,好比SSD。
三、 合理分配磁盤IO,把磁盤IO分散到多個設備上,以減小資源的競爭,提升並行操做能力。
四、 配置多核處理器,MySQL是多線程的數據庫,多處理器能夠提升同時執行多個線程的能力。
經過優化MySQL的參數能夠提升資源利用率,從而達到提升MySQL服務器性能的目的。
MySQL的配置參數都在my.conf或者my.ini文件的[mysqld]組中,經常使用的參數以下: