目錄
前言
MySQL 社區版是全球廣受歡迎的開源數據庫的免費下載版本。它遵循 GPL 許可協議,由龐大、活躍的開源開發人員社區提供支持。
MySQL 社區版包括:可插拔的存儲引擎架構、多種存儲引擎(InnoDB、MyISAM、NDB (MySQL Cluster)、Memory、Merge、Archive、CSV、等等)、MySQL 複製可提高應用性能和可擴展性、MySQL 分區有助於增強大型數據庫應用的性能和管理、存儲過程可提高開發人員效率、觸發器可在數據庫層面實施複雜的業務規則、視圖可確保敏感信息不受攻擊、Performance Schema 可監視各個用戶/應用的資源佔用情況、Information Schema 有助於方便地訪問元數據、MySQL 連接器(ODBC、JDBC、.NET 等)可以用多種語言構建應用、MySQL Workbench 可用於可視化建模、SQL 開發和管理。
本篇文章就圍繞MySQL的性能優化及系統資源優化進行,通過本篇文章將對MySQL的優化有一個更深入的瞭解!由於篇幅較長,爲了便於閱讀和記憶,所以博主將其分成了一、二部分,第一部分主講MySQL數據庫的結構優化、性能調優,第二部分主講系統資源調優、通過MySQL的系統配置參數實現。
MySQL性能調優和系統資源優化
一、MySQL性能調優和系統資源優化的目的
- 掌握 MySQL性能調優和系統資源優化到底優化了什麼;
- 掌握 MySQL查詢的優化方法;
- 掌握 MySQL數據庫結構的優化方法;
- 掌握 MySQL服務器的優化方法;
二、MySQL性能調優和系統資源優化到底優化了什麼
- 合理分配 MySQL資源、調整其系統參數使 MySQL運行速度更快、資源更節省;
- MySQL優化包括查詢優化、更新優化、服務器優化等;
- MySQL基本優化原則:減少系統瓶頸,減少資源佔用,增加系統的響應速度;
三、數據庫性能參數
使用 SHOW STATUS 語句查看MySQL數據庫的性能參數“ SHOW STATUS LIKE 'value' ”
如下圖:
常用的參數:
參數名 | 說明 |
---|---|
Slow_queries | 慢查詢次數 |
Com_% | MySQL的 CRUD相關操作的次數 |
Uptime | 上線總時長(或者連接到某個數據庫的總時長) |
Max_used_connections_time | 最開始的連接時間(連接到某個數據庫的時間點) |
更多優化參數配置,參看《 MySQL 性能優化實戰,MySQL 性能調優和系統資源優化解決方案(二) 》
四、查詢優化
關鍵字:EXPLAIN
在 MySQL 中可以使用 EXPLAIN 查看SQL語句的執行情況,用法:EXPLAIN SELECT * FROM table_name;
如下圖:
字段說明:
字段名 | 說明 |
---|---|
id | SELECT 識別符,這個表示SELECT查詢序列號 |
select_type |
表示 SELECT 語句的類型。取值: SIMPLE,表示簡單查詢,其中不包含連接查詢和子查詢; PRIMARY,表示主查詢,或者是最外面的查詢語句; UNION,表示連接查詢的第2個或後面的查詢語句; DEPENDENT UNION,UNION 中的第二個或後面的SELECT語句,取決於外面的查詢; UNION RESULT,連接查詢的結果; SUBQUERY,子查詢中的第1個SELECT語句; DEPENDENT SUBQUERY,子查詢中的第1個SELECT語句,取決於外面的查詢; DERIVED,SELECT(FROM 子句的子查詢) |
table | 表示查詢的表 |
partitions | 分區信息 |
type |
表示表的連接類型。以下的連接類型的順序是從最佳類型到最差類型: 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 值的行。在解決子查詢中經常使用該聯接類型的優化; 以上這五種情況都是很常見的索引使用情況;
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,對於每個來自於先前的表的行組合,進行完整的表掃描(這種類型的性能最差); |
possible_keys | 指出 MySQL 能使用哪個索引在該表中找到行。如果該列爲 NULL,說明沒有使用索引,可以對該列創建索引來提高性能。 |
key | 顯示 MySQL 實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL; |
key_len |
顯示 MySQL 決定使用的鍵長度。如果鍵是NULL,則長度爲NULL。 注意:key_len 是確定了 MySQL 將實際使用的索引長度。 |
ref | 顯示使用哪個列或常數與 key一起從表中選擇行。 |
rows | 顯示 MySQL 認爲它執行查詢時必須檢查的行數。 |
filtered | 過濾器 |
Extra |
該列包含 MySQL 解決查詢的詳細信息。取值如下: Distinct,MySQL 發現第1個匹配行後,停止爲當前的行組合搜索更多的行; |
查詢索引使用注意事項:索引可以提高查詢的速度,但並不是使用了帶有索引的字段查詢都會生效,有些情況下是不生效的,需要注意!
1、使用 LIKE關鍵字的查詢
在使用 LIKE關鍵字進行查詢時,如果匹配字符串的第一個字符爲“%”,索引不起作用,只有“%”不在第一個位置,索引纔會生效。
2、使用聯合索引的查詢
MySQL可以爲多個字段創建索引,一個索引可以包括16個字段。對於聯合索引,只有查詢條件中使用了這些字段中第一個字段時,索引纔會生效。
3、使用 OR關鍵字的查詢
查詢語句的查詢條件中只有OR關鍵字,且OR前後的兩個條件中的列都是索引時,索引纔會生效,否則,索引不生效。
五、數據庫結構優化
一個好的數據庫設計方案對於數據庫的性能往往會起到事半功倍的效果。需要考慮數據冗餘、查詢和更新的速度、字段的數據類型是否合理等多方面的內容。
1、將字段很多的表分解成多個表
對於字段較多的表,如果有些字段的使用頻率很低,可以將這些字段分離出來形成新表。因爲當一個表的數據量很大時,會由於使用頻率低的字段的存在而變慢。
2、增加中間表
對於需要經常聯合查詢的表,可以建立中間表以提高查詢效率。通過建立中間表,將需要通過聯合查詢的數據插入到中間表中,然後將原來的聯合查詢改爲對中間表的查詢。
3、增加冗餘字段
設計數據表時應儘量遵循範式理論的規約(數據庫設計三範式),儘可能的減少冗餘字段,讓數據庫設計看起來精緻、優雅。但是,合理的加入冗餘字段可以提高查詢速度。
表的規範化程度越高,表和表之間的關係越多,需要連接查詢的情況也就越多,性能也就越差。
* 注意:冗餘字段的值在一個表中修改了,就要想辦法在其他表中更新,否則就會導致數據不一致的問題!
六、數據庫數據操作優化
插入數據時,影響插入速度的主要是索引、唯一性校驗、一次插入的數據條數等。
插入數據的優化,不同的存儲引擎優化手段不一樣,現在許多數據庫管理系統都支持多種不同的存儲引擎。MySQL 的核心就是存儲引擎。
1、關於存儲引擎
數據庫存儲引擎是數據庫底層軟件組織,數據庫管理系統(DBMS)使用數據引擎進行創建、查詢、更新和刪除數據。不同的存儲引擎提供不同的底層實現(如:存儲機制,索引技巧,索引技巧,鎖定水平),底層實現的差異帶來的功能也就不同,在不同的場景下選擇合適的存儲引擎,可以讓數據庫的數據讀寫速度更快、效率更高。
MySQl數據庫中的引擎(9個):InnoDB、MRG_MYISAM、MEMORY、BLACKHOLE、MyISAM、CSV、ARCHIVE、PERFORMANCE_SCHEMA、FEDERATED。
InnoDB 事務型數據庫的首選引擎,支持事務安全表(ACID),支持行級鎖和外鍵。MySQL 5.5.x 之後,InnoDB 作爲默認存儲引擎。
MyISAM 是基於 ISAM的存儲引擎,並對其進行擴展,是在Web、數據倉儲和其他應用環境下最常使用的存儲引擎之一。MyISAM 擁有較高的插入、查詢速度,但不支持事務。
MEMORY 存儲引擎將表中的數據存儲到內存中,爲查詢和檢索其他數據提供快速訪問。
通過指令 “ SHOW ENGINES; ” 查看,如下圖:
常見的MySQL存儲引擎的異同:
功能 | InnoDB | MyISAM | MEMORY | ARCHIVE |
---|---|---|---|---|
存儲限制 | 64TB | 265TB | RAM | NONE |
支持事務 | YES | NO | NO | NO |
支持全文索引 | NO | YES | NO | NO |
支持B樹索引 | YES | YES | YES | NO |
支持哈希索引 | NO | NO | YES | NO |
支持集羣索引 | YES | NO | NO | NO |
支持數據索引 | YES | NO | YES | NO |
支持數據壓縮 | NO | YES | NO | NO |
支持外鍵 | YES | NO | NO | NO |
支持數據緩存 | YES | NO | N/A | NO |
空間使用率 | 高 | 低 | N/A | N/A |
查看錶的存儲引擎類型(常見的兩種查看方式):
SHOW CREATE TABLE tablename;
SHOW TABLE STATUS FROM dbname WHERE name = tablename;
如下圖:
或者
修改表的存儲引擎:
ALTER TABLE tablename ENGINE = InnoDB;
修改後如下圖:
存儲引擎的選型:
- InnoDB 用於事務處理應用程序,具有衆多特性,包括 ACID 事務支持。如果應用中需要執行大量的 INSERT 或 UPDATE 操作,則應該使用 InnoDB,這樣可以提高多用戶併發操作的性能;
- 如果數據表只用來大量新增、查詢的,MyISAM 引擎的效率更高;
- 如果只是臨時存放數據,數據量不大,並且不需要較高的數據安全性,可以選擇將數據存儲在基於 MEMORY引擎的數據表中,MySQL中使用該引擎作爲臨時表或中間表來存放查詢結果;
- 如果只提供高併發新增操作的,可以選擇 ARCHIVE引擎,ARCHIVE引擎支持高併發的插入操作,但是本身並不是事務安全的,Archive 引擎非常適合存儲歸檔數據,比如記錄系統日誌信息;
*注:在數據表中使用那種引擎需要根據實際的業務需求來判定,如果遇到需求變更,當前數據表的引擎不再適合於當前業務時,也可進行變更的操作(如何變更請往後看),一個數據庫中多個表可以使用不同的引擎以滿足各種性能和實際業務的需求,選擇合適的存儲引擎將會大大提高數據庫的整體性能。
2、InnoDB
InnoDB是目前 MySQL的默認存儲引擎,是目前使用最廣泛的存儲引擎。主要特點有:
- 支持事務(ACID)。默認的事務隔離級別爲可重複度,通過MVCC(併發版本控制)來實現的;
- 支持自動增長列,通過 auto_increment來實現;
- InnoDB使用的鎖粒度爲行級鎖,可以支持更高的併發;
- 支持從災難中恢復表(通過 bin-log日誌),容災性強;
- 支持外鍵約束,雖然外鍵約束降低了表的查詢速度,但是增加了表之間的耦合度;
- 配合熱備工具可以支持在線熱備份;
- 支持緩存(innodb_buffer_pool_size 來設置),通過緩衝池,將索引和數據全部緩存起來,加快查詢的速度;
- 其數據的物理組織形式是羣集表,所有的數據圍繞主鍵來組織,索引和數據放在一起,構成一個數據塊,位於B+樹的葉子節點上;
InnoDB 的存儲表和索引特點:
1)共享表空間存儲:所有的表和索引存放在同一個表空間中。
2)多表空間存儲:表結構放在frm文件,數據和索引放在IBD文件中。分區表的情況下,每個分區對應單獨的IBD文件。
3、MyISAM
MyISAM 是一個基於 ISAM存儲引擎,並對其進行擴展。它是在Web、數據倉儲和其他應用環境下最常使用的存儲引擎之一。MyISAM 擁有較高的數據新增、數據查詢速度,但不支持事物。
使用 MyISAM引擎創建數據庫,將產生3個文件,分別是(.frm, .MYD, .MYI):.frm 存儲表的定義(也就是表結構),.MYD 存儲表裏面的數據,.MYD 存儲索引。
MyISAM 特點:
- 支持大文件(長度可達63位),在大文件的文件系統和操作系統上被支持;
- 當刪除、更新、新增操作混合使用的時候,動態的數據行將產生更少的碎片。這要通過合併相鄰被刪除的塊,以及在下一個塊被刪除,就自動擴展到下一塊;
- 每個 MyISAM表最大索引數是爲64,可以通過重新編譯來變更;
- 最大的鍵長度是1000字節,可以通過重新編譯來變更;
- BLOB和TEXT類型的列可以被索引,支持FULLTEXT類型的索引,InnoDB不支持這種類型的索引;
- 索引列中允許爲NULL,長度爲0~1個字節;
- 數字鍵值以高字節優先被存儲以允許一個更高的索引壓縮;
- 每個 MyISAM類型的表都有一個AUTO_INCREMENT的內部列,當 INSERT和 UPDATE操作的時候該列被更新,同時AUTO_INCREMENT列將被刷新。所以說,MyISAM類型表的 AUTO_INCREMENT列更新比 InnoDB類型的AUTO_INCREMENT更快;
- 數據文件和索引文件放在不同目錄;
- 每個字符列可以有不同的字符集;
- VARCHAR 的列長度可固定可動態;
- VARCHAR和CHAR列可以多達64KB;
MyISAM 支持的三種存儲格式:
1)、靜態表(固定長度)
這種存儲格式的優點在於存儲速度非常快,容易發生緩存,而且表發生損壞後也容易修復。缺點是佔用的空間相對動態表較多。默認的存儲格式。
2)、動態表(可變長度)
優點是節省空間,缺點是一旦出錯恢復起來比較麻煩。佔用的空間相對靜態表較少,如果頻繁的更新刪除操作會產生碎片,需要定期執行 optimize table或 myisamchk -r命令來改善性能。
3)、壓縮表
使用 myisampack工具創建,佔用空間非常小,因爲每個記錄是被單獨壓縮的,訪問開支也非常的小。在數據文件發生錯誤時候,可以使用 check table工具來檢查,通過 repair table工具來恢復。
MyISAM和InnoDB的區別
- MyISAM 是非事務安全型的,InnoDB 是事務安全型的;
- MyISAM 鎖的粒度是表級,InnoDB 支持行級鎖定;
- MyISAM 支持全文類型索引,InnoDB 不支持全文索引;
- MyISAM 相對簡單,所以在效率上要優於 InnoDB,小型應用可以考慮使用 MyISAM;
- MyISAM 表是保存成文件的形式,在跨平臺的數據轉移中使用 MyISAM存儲會省去不少的麻煩;
- InnoDB 表比 MyISAM表更安全,可以在保證數據不會丟失的情況下,切換非事務表到事務表(ALTER TABLE tablename ENGINE = InnoDB);
4、MEMORY
MEMORY 引擎默認使用哈希(HASH)索引,其速度比B樹要快,但也可以使用B樹索引。由於 MEMORY引擎所存儲的數據都被保存在內存中,以供查詢和引用的其他表數據實現快速訪問,但是其保存的數據是具有不穩定性的,如果一旦 mysqld進程發生異常、重啓或服務器異常宕機等情況都會導致數據的丟失。MEMORY 引擎一般適用於生命週期短,且只使用一次的數據表。所以,一般都是在創建臨時表時纔會使用到。
MEMORY 特點:
- 表中可以存在非唯一鍵值;
- 對於字符串類型的數據,只支持固定長度的行,並且 VARCHAR會被自動存儲爲 CHAR類型;
- 不支持BLOB或TEXT類型;
- 支持 AUTO_INCREMENT列和可包含NULL值的列的索引;
- 在所由客戶端之間共享;
- 不在使用的內容,需要釋放其佔用的內存空間,通過執行DELETE FROM或TRUNCATE TABLE,或者刪除整個表(使用DROP TABLE)來釋放佔用的資源;
5、其它引擎
ARCHIVE
ARCHIVE > 歸檔,僅僅支持插入和查詢兩種功能。ARCHIVE 在 MySQL5.5以後支持索引功能,支持良好的壓縮機制,使用zlib實現壓縮,在記錄請求的時候實時壓縮,經常被用來作爲倉庫使用。適用於存儲大量的獨立的作爲歷史記錄的數據,例如系統日誌的記錄,對插入速度要求較高,查詢不經常使用的,因爲該引擎對查詢的支持較差。
CSV
文件結構組成包括:.frm表結構描述、.csv數據、.csm表狀態、當前記錄數量等。
特點:
- 沒有索引、不能爲NULL、不支持自增長;
- 更新和刪除時先寫入到臨時文件,然後在 rnd_end()函數中重新生成數據文件;
- 支持直接編輯數據文件;
- 以CSV引擎存儲的數據,引號包含,逗號隔開;
- 數據以文本方式存儲在文件中;
- CSV引擎可以將csv文件作爲 MySQL的表進行處理,其存儲格式類似於普通的csv文件;
BLACKHOLE
BLACKHOLE 引擎支持事務,而且支持 mvcc的行級鎖,寫入 BLACKHOLE引擎表中的任何數據都會消失,主要用於做日誌記錄或同步歸檔的中繼存儲,BLACKHOLE 引擎除非有要求使用,否則不會使用到。
PERFORMANCE_SCHEMA
PERFORMANCE_SCHEMA 引擎是MySql 5.5新推出的一個引擎,主要是用來收集數據庫服務器的性能參數。但是我們無法創建該類型的表,需要在配置文件my.cnf中進行配置才能生效。
特點:
- 提供進程的詳細信息,包括鎖、互斥變量、文件信息;
- 歷史的事件彙總信息,提供爲 MySql服務器的性能情況做出判斷;
- 對新增和刪除監控事件點都非常容易,並可以隨意的改變 Mysql服務器的監控週期;
FEDERATED
FEDERATED 引擎可以將不同的 Mysql服務器聯合起來,在邏輯上組成一個完整的數據庫,FEDERATED引擎非常適合分佈式數據庫應用。
FEDERATED 引擎支持在本地數據庫中訪問遠程數據庫中的數據,發送到 FEDERATED引擎表的查詢請求會被轉發送到遠程數據庫的表上執行,而 FEDERATED引擎數據庫本身是不存儲數據的。
特點:
- 不支持事務;
- 不支持表結構修改;
- 不支持ALTER TABLE指令;
- 執行TRUNCATE指令時,會同時清楚遠程關聯表中的數據;
- 執行DROP指令時,不會刪除遠程關聯表;
- 本地的表結構必須同遠程的完全一致;
- 遠程關聯表僅限於MySQL;
- 本地表與遠程關聯表通過 TCP長連接進行的,支持多客戶端使用,所以不用擔心頻繁建立連接帶來的網絡帶寬的開銷;
- 一般創建的表會生成表的定義文件和數據文件,通過 FEDERATED引擎創建的表只在本地生成表的定義文件,數據文件則存在於與之關聯的遠程數據庫中,通過 FEDERATED引擎可以實現類似於 Oracle下DBLINK的遠程數據訪問功能;
6、數據庫引擎優化
MyISAM
禁用索引,對於非空表,插入記錄時,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:
當需要批量導入數據時,使用 LOAD DATA INFILE語句比 INSERT語句插入速度快很多。
InnoDB
禁用唯一性檢查:
用法同MyISAM一樣。
禁用外鍵檢查:
插入數據之前執行禁止對外鍵的檢查,數據插入完成後再恢復,可以提高插入速度。
禁用:SET FOREIGN_KEY_CHECKS = 0;
開啓:SET FOREIGN_KEY_CHECKS = 1;
禁止自動提交:
插入數據之前執行禁止事務的自動提交,數據插入完成後再恢復,可以提高插入速度。
禁用:SET AUTOCOMMIT = 0;
開啓:SET AUTOCOMMIT = 1;
七、子查詢優化
MySQL 從4.1版本開始支持子查詢,使用子查詢進行 SELECT語句嵌套查詢,可以一次完成很多邏輯上需要多個步驟才能完成的 SQL操作。子查詢雖然很靈活,但是執行效率並不高。執行子查詢時,MYSQL首先需要創建臨時表,查詢完畢後再刪除這些臨時表,所以,子查詢的速度會受到一定的影響。
子查詢優化方法
可以使用連接查詢(JOIN)來代替子查詢,連接查詢時不需要建立臨時表,其速度比子查詢快。
參考文檔:
MySQL中文官網:【MySQL 性能調優和優化資源】
好了,關於 MySQL 性能優化實戰,MySQL 性能調優和系統資源優化解決方案(一) 就寫到這兒了,如果還有什麼疑問或遇到什麼問題歡迎掃碼提問,也可以給我留言哦,我會一一詳細的解答的。
歇後語:“ 共同學習,共同進步 ”,也希望大家多多關注CSND的IT社區。
作 者: | 華 仔 |
聯繫作者: | [email protected] |
來 源: | CSDN (Chinese Software Developer Network) |
原 文: | https://blog.csdn.net/Hello_World_QWP/article/details/104900695 |
版權聲明: | 本文爲博主原創文章,請在轉載時務必註明博文出處! |