MySQL架構mysql
查詢執行流程
查詢執行的流程是怎樣的:算法
鏈接
1.1客戶端發起一條Query請求,監聽客戶端的‘鏈接管理模塊’接收請求
1.2將請求轉發到‘鏈接進/線程模塊’
1.3調用‘用戶模塊’來進行受權檢查
1.4經過檢查後,‘鏈接進/線程模塊’從‘線程鏈接池’中取出空閒的被緩存的鏈接線程和客戶端請求對接,若是失敗則建立一個新的鏈接請求。
處理
2.1先查詢緩存,檢查Query語句是否徹底匹配,
2.2查詢緩存失敗則轉交給‘命令解析器’
2.3再轉交給對應的模塊處理
2.4若是是SELECT查詢還會經由‘查詢優化器’作大量的優化,生成執行計劃
2.5模塊收到請求後,經過‘訪問控制模塊’檢查所鏈接的用戶是否有訪問目標表和目標字段的權限
2.6有則調用‘表管理模塊’,先是查看table cache中是否存在,有則直接對應的表和獲取鎖,不然從新打開表文件
2.8根據表的meta數據,獲取表的存儲引擎類型等信息,經過接口調用對應的存儲引擎處理
2.9上述過程當中產生數據變化的時候,若打開日誌功能,則會記錄到相應二進制日誌文件中
結果
3.1Query請求完成後,將結果集返回給‘鏈接進/線程模塊’
3.2返回的也能夠是相應的狀態標識,如成功或失敗等
3.3‘鏈接進/線程模塊’進行後續的清理工做,並繼續等待請求或斷開與客戶端的鏈接
什麼是優化
合理安排資源、調整系統參數使MySQL運行更快、更節省資源。
優化是多方面的,包括查詢、表設計、服務器等。
原則:減小系統瓶頸,減小資源佔用,增長系統的反應速度。
查詢優化
在優化MySQL時,一般須要庫進行分析。常見的分析手段有慢查詢日誌,EXPLAIN 分析查詢,經過定位分析性能的瓶頸,才能更好的優化數據庫系統的性能。sql
慢查詢日誌
慢查詢日誌開啓
在配置文件my.cnf或my.ini中在[mysqld]一行下面加入兩個配置參數
log-slow-queries=/data/mysqldata/slow-query.log
long_query_time=5
注:log-slow-queries參數爲慢查詢日誌存放的位置,通常這個目錄要有mysql的運行賬號的可寫權限,通常都將這個目錄設置爲mysql的數據存放目錄;
long_query_time=5中的5表示查詢超過五秒才記錄;
還能夠在my.cnf或者my.ini中添加log-queries-not-using-indexes參數,表示記錄下沒有使用索引的查詢。
慢查詢分析
咱們能夠經過打開log文件查看得知哪些SQL執行效率低下
從日誌中,能夠發現查詢時間超過5 秒的SQL,而小於5秒的沒有出如今此日誌中。
若是慢查詢日誌中記錄內容不少,可使用mysqldumpslow工具(MySQL客戶端安裝自帶)來對慢查詢日誌進行分類彙總。mysqldumpslow對日誌文件進行了分類彙總,顯示彙總後摘要結果。
進入log的存放目錄,運行
[root@mysql_data]#mysqldumpslow slow-query.log
Reading mysql slow query log from slow-query.log
Count: 2 Time=11.00s (22s) Lock=0.00s (0s) Rows=1.0 (2), root[root]@mysql
select count(N) from t_user;數據庫
mysqldumpslow命令
/path/mysqldumpslow -s c -t 10 /database/mysql/slow-query.log
這會輸出記錄次數最多的10條SQL語句,其中:緩存
-s, 是表示按照何種方式排序,c、t、l、r分別是按照記錄次數、時間、查詢時間、返回的記錄數來排序,ac、at、al、ar,表示相應的倒敘
-t, 是top n的意思,即爲返回前面多少條的數據;
-g, 後邊能夠寫一個正則匹配模式,大小寫不敏感的;安全
例如:
/path/mysqldumpslow -s r -t 10 /database/mysql/slow-log
獲得返回記錄集最多的10個查詢。
/path/mysqldumpslow -s t -t 10 -g 「left join」 /database/mysql/slow-log
獲得按照時間排序的前10條裏面含有左鏈接的查詢語句。服務器
使用mysqldumpslow命令能夠很是明確的獲得各類咱們須要的查詢語句,對MySQL查詢語句的監控、分析、優化是MySQL優化很是重要的一步。開啓慢查詢日誌後,因爲日誌記錄操做,在必定程度上會佔用CPU資源影響mysql的性能,可是能夠階段性開啓來定位性能瓶頸。網絡
EXPLAIN
在MySQL中可使用EXPLAIN查看SQL執行計劃,用法:EXPLAIN SELECT * FROM products
5.2.1.id
SELECT識別符。這是SELECT查詢序列號。這個不重要。
5.2.2.select_type
表示SELECT語句的類型。
例如:
一、SIMPLE
表示簡單查詢,其中不包含鏈接查詢和子查詢。
二、PRIMARY
表示主查詢,或者是最外面的查詢語句。
三、UNION
表示鏈接查詢的第2個或後面的查詢語句。
5.2.3.table
表示查詢的表。
5.2.4.type
表示表的鏈接類型。
如下的鏈接類型的順序是從最佳類型到最差類型:
一、system
表僅有一行,這是const類型的特列,平時不會出現,這個也能夠忽略不計。
二、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
對於每一個來自於先前的表的行組合,進行完整的表掃描。(性能最差)
5.2.5.possible_keys
指出MySQL能使用哪一個索引在該表中找到行。
若是該列爲NULL,說明沒有使用索引,能夠對該列建立索引來提升性能。
5.2.6.key
顯示MySQL實際決定使用的鍵(索引)。若是沒有選擇索引,鍵是NULL。
5.2.7.key_len
顯示MySQL決定使用的鍵長度。若是鍵是NULL,則長度爲NULL。
注意:key_len是肯定了MySQL將實際使用的索引長度。
5.2.8.ref
顯示使用哪一個列或常數與key一塊兒從表中選擇行。
5.2.9.rows
顯示MySQL認爲它執行查詢時必須檢查的行數。
5.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 BY或DISTINCT查詢的全部列,而不要額外搜索硬盤訪問實際的表。數據結構
索引使用
6.1.1.MySQL索引
6.1.1.1.B-Tree索引
通常來講,MySQL中的B-Tree索引的物理文件大多都是以二叉樹的結構來存儲的,也就是全部實際須要的數據都存放於樹的葉子節點,並且到任何一個葉子節點的最短路徑的長度都是徹底相同的。
6.1.1.2.R-Tree索引
RTREE在mysql不多使用,支持該類型的存儲引擎只有MyISAM、BDb、InnoDb、NDb、Archive幾種。相對於BTREE,RTREE的優點在於範圍查找.
6.1.1.3.Hash索引
Hash索引在MySQL中使用的並非不少,目前主要是Memory存儲引擎使用,並且在Memory存儲引擎中將Hash索引做爲默認的索引類型。所謂Hash索引,實際上就是經過必定的Hash算法,將須要索引的鍵值進行Hash運算,而後將獲得的Hash值存入一個Hash表中。而後每次須要檢索的時候,都會將檢索條件進行相同算法的Hash運算,而後再和Hash表中的Hash值進行比較並得出相應的信息。
Hash索引僅僅只能知足「=」,「IN」和「<=>」查詢,不能使用範圍查詢;
Hash索引沒法被利用來避免數據的排序操做;
Hash索引不能利用部分索引鍵查詢;
Hash索引在任什麼時候候都不能避免表掃面;
Hash索引遇到大量Hash值相等的狀況後性能並不必定就會比B-Tree索引高;
6.1.1.4.Full-text索引
Full-text索引也就是咱們常說的全文索引,目前在MySQL中僅有MyISAM存儲引擎支持,並且也並非全部的數據類型都支持全文索引。目前來講,僅有CHAR,VARCHAR和TEXT這三種數據類型的列能夠建Full-text索引。
6.1.2.建立索引
是否須要建立索引,幾點原則:架構
較頻繁的做爲查詢條件的字段應該建立索引;
惟一性太差的字段不適合單首創建索引,即便頻繁做爲查詢條件;
更新很是頻繁的字段不適合建立索引;
不會出如今WHERE子句中的字段不應建立索引;
索引可以極大的提升數據檢索效率,也可以改善排序分組操做的性能,可是咱們不能忽略的一個問題就是索引是徹底獨立於基礎數據以外的一部分數據,更新數據會帶來的IO量和調整索引所致的計算量的資源消耗。
6.1.3.使用索引
6.1.3.1.使用聯合索引的查詢
MySQL能夠爲多個字段建立索引,一個索引能夠包括16個字段。對於聯合索引,只有查詢條件中使用了這些字段中第一個字段時,索引纔會生效。
6.1.3.2.使用OR關鍵字的查詢
查詢語句的查詢條件中只有OR關鍵字,且OR先後的兩個條件中的列都是索引時,索引纔會生效,不然,索引不生效。
存儲優化
存儲數據時,影響存儲速度的主要是索引、惟一性校驗、一次存儲的數據條數等。
存儲數據的優化,不一樣的存儲引擎優化手段不同,在MySQL中經常使用的存儲引擎有,MyISAM和InnoDB,二者的區別:
7.1.存儲引擎介紹
7.1.1.MyISAM存儲引擎
MyISAM存儲引擎是一種非事務性的引擎,提供高速存儲和檢索,以及全文搜索能力,適合數據倉庫等查詢頻繁的應用。
每個表都被存放爲三個以表名命名的物理文件。有存放表結構定義信息的.frm文件,還有存放了表的數據.MYD文件和存放索引數據的.MYI文件。
7.1.2.Innodb 存儲引擎
Innodb 存儲引擎是事務安全的, 所以若是須要一個事務安全的存儲引擎,建議使用它。若是你的數據執行大量的INSERT或UPDATE,出於性能方面的考慮應該使用InnoDB表。
InnoDB 給 MySQL 提供了具備事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行鎖(locking on row level),提供與 Oracle 類型一致的不加鎖讀取(non-locking read in SELECTs)。這些特性均提升了多用戶併發操做的性能表現。
在InnoDB表中不須要擴大鎖定(lock escalation),由於 InnoDB 的列鎖定(row level locks)適宜很是小的空間。InnoDB 是 MySQL 上提供外鍵約束(FOREIGN KEY constraints)的表引擎。
InnoDB 的設計目標是處理大容量數據庫系統,它的 CPU 利用率是其它基於磁盤的關係數據庫引擎所不能比的。在技術上,InnoDB 是一套放在 MySQL 後臺的完整數據庫系統,InnoDB 在主內存中創建其專用的緩衝池用於高速緩衝數據和索引。
InnoDB 把數據和索引存放在表空間裏,可能包含多個文件,這與MyISAM不同。InnoDB 表的大小隻受限於操做系統的文件大小,通常爲 2 GB。InnoDB全部的表都保存在同一個數據文件 ibdata1 中(也多是多個文件,或者是獨立的表空間文件),相對來講比較很差備份。備份的方案能夠是拷貝數據文件、備份 binlog,或者用 mysqldump。
7.2.MyISAM和Innodb的區別
InnoDB和MyISAM是許多人在使用MySQL時最經常使用的兩個表類型,這兩個表類型各有優劣,視具體應用而定。基本的差異爲:MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持已經外部鍵等高級數據庫功能。
7.2.1.具體實現的差異:
MyISAM是非事務安全型的,而InnoDB是事務安全型的。
MyISAM鎖的粒度是表級,而InnoDB支持行級鎖定。
MyISAM支持全文類型索引,而InnoDB不支持全文索引。
MyISAM相對簡單,因此在效率上要優於InnoDB,小型應用能夠考慮使用MyISAM。
MyISAM表是保存成文件的形式,在跨平臺的數據轉移中使用MyISAM存儲會省去很多的麻煩。
InnoDB表比MyISAM表更安全,能夠在保證數據不會丟失的狀況下,切換非事務表到事務表(alter table tablename type=innodb)。
7.2.2.應用場景
MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。若是應用中須要執行大量的SELECT查詢,那麼MyISAM是更好的選擇。
InnoDB用於事務處理應用程序,具備衆多特性,包括ACID事務支持。若是應用中須要執行大量的INSERT或UPDATE操做,則應該使用InnoDB,這樣能夠提升多用戶併發操做的性能。
7.3.MyISAM存儲優化
7.3.1.禁用索引
對於非空表,插入記錄時,MySQL會根據表的索引對插入的記錄創建索引。若是插入大量數據,創建索引會下降插入數據速度。
爲了解決這個問題,能夠在批量插入數據以前禁用索引,數據插入完成後再開啓索引。
禁用索引的語句:
ALTER TABLE table_name DISABLE KEYS
開啓索引語句:
ALTER TABLE table_name ENABLE KEYS
對於空表批量插入數據,則不須要進行操做,由於MyISAM引擎的表是在導入數據後才創建索引。
7.3.2.禁用惟一性檢查
惟一性校驗會下降插入記錄的速度,能夠在插入記錄以前禁用惟一性檢查,插入數據完成後再開啓。
禁用惟一性檢查的語句:SET UNIQUE_CHECKS = 0;
開啓惟一性檢查的語句:SET UNIQUE_CHECKS = 1;
7.3.3.批量插入數據
插入數據時,可使用一條INSERT語句插入一條數據,也能夠插入多條數據。
7.3.4.使用LOAD DATA INFILE
當須要批量導入數據時,使用LOAD DATA INFILE語句比INSERT語句插入速度快不少。
7.4.InnoDB
7.4.1.禁用惟一性檢查
用法和MyISAM同樣。
7.4.2.禁用外鍵檢查
插入數據以前執行禁止對外鍵的檢查,數據插入完成後再恢復,能夠提供插入速度。
禁用:SET foreign_key_checks = 0;
開啓:SET foreign_key_checks = 1;
7.4.3.禁止自動提交
插入數據以前執行禁止事務的自動提交,數據插入完成後再恢復,能夠提升插入速度。
禁用:SET autocommit = 0;
開啓:SET autocommit = 1;
數據庫結構優化
8.1.優化表結構
儘可能將表字段定義爲NOT NULL約束,這時因爲在MySQL中含有空值的列很難進行查詢優化,NULL值會使索引以及索引的統計信息變得很複雜。
對於只包含特定類型的字段,可使用enum、set 等符合數據類型。
數值型字段的比較比字符串的比較效率高得多,字段類型儘可能使用最小、最簡單的數據類型。例如P地址可使用int類型。
儘可能使用TINYINT、SMALLINT、MEDIUM_INT做爲整數類型而非INT,若是非負則加上UNSIGNED
VARCHAR的長度只分配真正須要的空間
儘可能使用TIMESTAMP而非DATETIME,
單表不要有太多字段,建議在20之內
合理的加入冗餘字段能夠提升查詢速度。
8.2.表拆分
8.2.1.垂直拆分
垂直拆分按照字段進行拆分,其實就是把組成一行的多個列分開放到不一樣的表中,這些表具備不一樣的結構,拆分後的表具備更少的列。例如用戶表中的一些字段可能常常訪問,能夠把這些字段放進一張表裏。另一些不常用的信息就能夠放進另一張表裏。
插入的時候使用事務,也能夠保證兩表的數據一致。缺點也很明顯,因爲拆分出來的兩張表存在一對一的關係,須要使用冗餘字段,並且須要join操做,咱們在使用的時候能夠分別取兩次,這樣的來講既能夠避免join操做,又能夠提升效率。
8.2.2.水平拆分
水平拆分按照行進行拆分,常見的就是分庫分表。以用戶表爲例,能夠取用戶ID,而後對ID取10的餘數,將用戶均勻的分配進這 0-9這10個表中。查找的時候也按照這種規則,又快又方便。
有些表業務關聯比較強,那麼可使用按時間劃分的。例如天天的數據量很大,須要天天新建一張表。這種業務類型就是須要高速插入,可是對於查詢的效率不太關心。表越大,插入數據所須要索引維護的時間也就越長。
8.3.分區
使用分區是大數據處理後的產物。好比系統用戶的註冊推廣等等,會產生海量的日誌,固然也能夠按照時間水平拆分,創建多張表。但在實際操做中,容易發生忘記切換表致使數據錯誤。
分區適用於例如日誌記錄,查詢少。通常用於後臺的數據報表分析。對於這些數據彙總需求,須要不少日誌表去作數據聚合,咱們可以容忍1s到2s的延遲,只要數據準確可以知足需求就能夠。
MySQL主要支持4種模式的分區:range分區、list預約義列表分區,hash 分區,key鍵值分區。
8.4.讀寫分離
大型網站會有大量的併發訪問,若是仍是傳統的數據結構,或者只是單單靠一臺服務器扛,如此多的數據庫鏈接操做,數據庫必然會崩潰,數據丟失的話,後果更是不堪設想。這時候,咱們須要考慮如何減小數據庫的聯接。
咱們發現通常狀況對數據庫而言都是「讀多寫少」,也就說對數據庫讀取數據的壓力比較大,這樣分析能夠採用數據庫集羣的方案。其中一個是主庫,負責寫入數據,咱們稱爲寫庫;其它都是從庫,負責讀取數據,咱們稱爲讀庫。這樣能夠緩解一臺服務器的訪問壓力
8.5.數據庫集羣
若是訪問量很是大,雖然使用讀寫分離可以緩解壓力,可是一旦寫操做一臺服務器都不能承受了,這個時候咱們就須要考慮使用多臺服務器實現寫操做。
例如可使用MyCat搭建MySql集羣,對ID求3的餘數,這樣能夠把數據分別存放到3臺不一樣的服務器上,由MyCat負責維護集羣節點的使用。
硬件優化
是服務器的硬件性能直接決定着MySQL數據庫的性能,硬件的性能瓶頸,直接決定MySQL數據庫的運行速度和效率。
能夠從如下幾個方面考慮:
一、配置較大的內存。足夠大的內存,是提升MySQL數據庫性能的方法之一。內存的IO比硬盤快的多,能夠增長系統的緩衝區容量,使數據在內存停留的時間更長,以減小磁盤的IO。
二、磁盤I/O相關
使用SSD或者PCIe SSD設備,至少得到數百倍甚至萬倍的IOPS提高;購置陣列卡同時配備CACHE及BBU模塊,可明顯提高IOPS儘量選用RAID-10,而非RAID-5使用機械盤的話,儘量選擇高轉速的,例如選用15000RPM,而不是7200RPM的盤三、配置CPU相關 在服務器的BIOS設置中,可調整下面的幾個配置:選擇Performance Per Watt Optimized(DAPC)模式,發揮CPU最大性能;關閉C1E和C States等選項,提高CPU效率;Memory Frequency(內存頻率)選擇Maximum Performance;MySQL緩存爲了提升查詢速度,咱們能夠經過不一樣的方式去緩存咱們的結果從而提升響應效率。當咱們的數據庫打開了Query Cache(簡稱QC)功能後,數據庫在執行SELECT語句時,會將其結果放到QC中,當下一次處理一樣的SELECT請求時,數據庫就會從QC取得結果,而不須要去數據表中查詢。若是緩存命中率很是高的話,有測試代表在極端狀況下能夠提升效率238%。但一個緩存機制是否有效,效果如何,倒是一個須要好好思考的問題。Query Cache有以下規則,若是數據表被更改,那麼和這個數據表相關的所有Cache所有都會無效,並刪除之。這裏「數據表更改」包括: INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等。舉個例子,若是數據表item訪問頻繁,那麼意味着它的不少數據會被QC緩存起來,可是每一次item數據表的更新,不管更新是否是影響到了cache 的數據,都會將所有和item表相關的cache清除。若是你的數據表更新頻繁的話,那麼Query Cache將會成爲系統的負擔。有實驗代表,糟糕時,QC會下降系統13%的處理能力。10.1.1.全局緩存數據庫屬於IO密集型的應用程序,其主職責就是數據的管理及存儲工做。而咱們知道,從內存中讀取一個數據庫的時間是微秒級別,而從一塊普通硬盤上讀取一個 IO是在毫秒級別,兩者相差3個數量級。因此,要優化數據庫,首先第一步須要優化的就是IO,儘量將磁盤IO轉化爲內存IO,也就是使用緩存啓動MySQL時就要分配而且老是存在的全局緩存,能夠在MySQL的my.conf或者my.ini文件的[mysqld]組中配置。目前有:key_buffer_size(默認值:402653184,即384M)、innodb_buffer_pool_size(默認值:134217728即:128M)、innodb_additional_mem_pool_size(默認值:8388608即:8M)、innodb_log_buffer_size(默認值:8388608即:8M)、query_cache_size(默認值:33554432即:32M)等五個。總共:560M.10.1.1.1.key_buffer_sizekey_buffer_size是用於索引塊的緩衝區大小,增長它可獲得更好處理的索引(對全部讀和多重寫),對MyISAM表性能影響最大的一個參數。若是你使它太大,系統將開始換頁而且真的變慢了。嚴格說是它決定了數據庫索引處理的速度,尤爲是索引讀的速度。對於內存在4GB左右的服務器該參數可設置爲256M或384M.10.1.1.2.innodb_buffer_pool_sizeinnodb_buffer_pool_size:主要針對InnoDB表性能影響最大的一個參數。功能與Key_buffer_size同樣。InnoDB佔用的內存,除innodb_buffer_pool_size用於存儲頁面緩存數據外,另外正常狀況下還有大約8%的開銷,主要用在每一個緩存頁幀的描述、adaptive hash等數據結構,若是不是安全關閉,啓動時還要恢復的話,還要另開大約12%的內存用於恢復,二者相加就有差很少21%的開銷。10.1.1.3.innodb_additional_mem_pool_sizeinnodb_additional_mem_pool_size 設置了InnoDB存儲引擎用來存放數據字典信息以及一些內部數據結構的內存空間大小,因此當咱們一個MySQL Instance中的數據庫對象很是多的時候,是須要適當調整該參數的大小以確保全部數據都能存放在內存中提升訪問效率的。10.1.1.4.innodb_log_buffer_sizeinnodb_log_buffer_size這是InnoDB存儲引擎的事務日誌所使用的緩衝區。相似於Binlog BufferInnoDB在寫事務日誌的時候,爲了提升性能,也是先將信息寫入Innofb Log Buffer中,當知足innodb_flush_log_trx_commit參數所設置的相應條件(或者日誌緩衝區寫滿)以後,纔會將日誌寫到文件 (或者同步到磁盤)中。能夠經過innodb_log_buffer_size 參數設置其可使用的最大內存空間。InnoDB 將日誌寫入日誌磁盤文件前的緩衝大小。理想值爲 1M 至 8M。大的日誌緩衝容許事務運行時不須要將日誌保存入磁盤而只到事務被提交(commit)。 所以,若是有大的事務處理,設置大的日誌緩衝能夠減小磁盤I/O。 這個參數實際上還和另外的flush參數相關。通常來講不建議超過32MB10.1.1.5.query_cache_sizequery_cache_size: 主要用來緩存MySQL中的ResultSet,也就是一條SQL語句執行的結果集,因此僅僅只能針對select語句。當咱們打開了 Query Cache功能,MySQL在接受到一條select語句的請求後,若是該語句知足Query Cache的要求,MySQL會直接根據預先設定好的HASH算法將接受到的select語句以字符串方式進行hash,而後到Query Cache中直接查找是否已經緩存。若是已經在緩存中,該select請求就會直接將數據返回,從而省略了後面全部的步驟(如SQL語句的解析,優化器優化以及向存儲引擎請求數據等),極大的提升性能。固然,Query Cache也有一個致命的缺陷,那就是當某個表的數據有任何任何變化,都會致使全部引用了該表的select語句在Query Cache中的緩存數據失效。因此,當咱們的數據變化很是頻繁的狀況下,使用Query Cache可能會得不償失10.1.2.局部緩存除了全局緩衝,MySql還會爲每一個鏈接發放鏈接緩衝。個鏈接到MySQL服務器的線程都須要有本身的緩衝。大概須要馬上分配256K,甚至在線程空閒時,它們使用默認的線程堆棧,網絡緩存等。事務開始以後,則須要增長更多的空間。運行較小的查詢可能僅給指定的線程增長少許的內存消耗,然而若是對數據表作複雜的操做例如掃描、排序或者須要臨時表,則需分配大約read_buffer_size,sort_buffer_size,read_rnd_buffer_size,tmp_table_size 大小的內存空間. 不過它們只是在須要的時候才分配,而且在那些操做作完以後就釋放了。10.1.2.1.read_buffer_sizeread_buffer_size是MySql讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql會爲它分配一段內存緩衝區。read_buffer_size變量控制這一緩衝區的大小。若是對錶的順序掃描請求很是頻繁,而且你認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能.10.1.2.2.sort_buffer_sizesort_buffer_size是MySql執行排序使用的緩衝大小。若是想要增長ORDER BY的速度,首先看是否可讓MySQL使用索引而不是額外的排序階段。若是不能,能夠嘗試增長sort_buffer_size變量的大小10.1.2.3.read_rnd_buffer_sizeread_rnd_buffer_size 是MySql的隨機讀緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySql會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySql會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開銷過大。10.1.2.4.tmp_table_sizetmp_table_size是MySql的heap (堆積)表緩衝大小。全部聯合在一個DML指令內完成,而且大多數聯合甚至能夠不用臨時表便可以完成。大多數臨時表是基於內存的(HEAP)表。具備大的記錄長度的臨時表 (全部列的長度的和)或包含BLOB列的表存儲在硬盤上。若是某個內部heap(堆積)表大小超過tmp_table_size,MySQL能夠根據須要自動將內存中的heap表改成基於硬盤的MyISAM表。還能夠經過設置tmp_table_size選項來增長臨時表的大小。也就是說,若是調高該值,MySql同時將增長heap表的大小,可達到提升聯接查詢速度的效果。10.1.2.5.record_buffer:record_buffer每一個進行一個順序掃描的線程爲其掃描的每張表分配這個大小的一個緩衝區。若是你作不少順序掃描,你可能想要增長該值。10.1.3.其它緩存10.1.3.1.table_cacheTABLE_CACHE(5.1.3及之後版本又名TABLE_OPEN_CACHE),table_cache指定表高速緩存的大小。每當MySQL訪問一個表時,若是在表緩衝區中還有空間,該表就被打開並放入其中,這樣能夠更快地訪問表內容。不能盲目地把table_cache設置成很大的值。若是設置得過高,可能會形成文件描述符不足,從而形成性能不穩定或者鏈接失敗。4.2.3.2 thread_cache_size (服務器線程緩存)默認的thread_cache_size=8,,這個值表示能夠從新利用保存在緩存中線程的數量,當斷開鏈接時若是緩存中還有空間,那麼客戶端的線程將被放到緩存中,若是線程從新被請求,那麼請求將從緩存中讀取,若是緩存中是空的或者是新的請求,那麼這個線程將被從新建立,若是有不少新的線程,增長這個值能夠改善系統性能.經過比較 Connections 和 Threads_created 狀態的變量,能夠看到這個變量的做用。11.MySQL服務器參數經過優化MySQL的參數能夠提升資源利用率,從而達到提升MySQL服務器性能的目的。MySQL的配置參數都在my.conf或者my.ini文件的[mysqld]組中,經常使用的參數以下:11.1.back_logback_log值指出在MySQL暫時中止回答新請求以前的短期內多少個請求能夠被存在堆棧中(每一個鏈接256kb,佔用:125M)。也就是說,若是MySql的鏈接數據達到max_connections時,新來的請求將會被存在堆棧中,以等待某一鏈接釋放資源,該堆棧的數量即back_log,若是等待鏈接的數量超過back_log,將不被授予鏈接資源。11.2.wait_timeout當MySQL鏈接閒置超過必定時間後將會被強行關閉。MySQL默認的wait-timeout值爲8個小時。設置這個值是很是有意義的,好比你的網站有大量的MySQL連接請求(每一個MySQL鏈接都是要內存資源開銷的),因爲你的程序的緣由有大量的鏈接請求空閒啥事也不幹,白白佔用內存資源,或者致使MySQL超過最大鏈接數歷來沒法新建鏈接致使「Too many connections」的錯誤。在設置以前你能夠查看一下你的MYSQL的狀態(可用showprocesslist),若是常常發現MYSQL中有大量的Sleep進程,則須要 修改wait-timeout值了。11.3.max_connectionsmax_connections是指MySql的最大鏈接數,若是服務器的併發鏈接請求量比較大,建議調高此值,以增長並行鏈接數量,固然這創建在機器能支撐的狀況下,由於若是鏈接數越多,介於MySql會爲每一個鏈接提供鏈接緩衝區,就會開銷越多的內存,因此要適當調整該值,不能盲目提升設值。MySQL服務器容許的最大鏈接數1638411.4.max_user_connectionsmax_user_connections是指每一個數據庫用戶的最大鏈接針對某一個帳號的全部客戶端並行鏈接到MYSQL服務的最大並行鏈接數。簡單說是指同一個帳號可以同時鏈接到mysql服務的最大鏈接數。設置爲0表示不限制。11.5.thread_concurrencythread_concurrency的值的正確與否, 對mysql的性能影響很大, 在多個cpu(或多核)的狀況下,錯誤設置了thread_concurrency的值, 會致使mysql不能充分利用多cpu(或多核), 出現同一時刻只能一個cpu(或核)在工做的狀況。thread_concurrency應設爲CPU核數的2倍。11.6.skip-name-resolveskip-name-resolve:禁止MySQL對外部鏈接進行DNS解析,使用這一選項能夠消除MySQL進行DNS解析的時間。但須要注意,若是開啓該選項,則全部遠程主機鏈接受權都要使用IP地址方式,不然MySQL將沒法正常處理鏈接請求!11.7.default-storage-enginedefault-storage-engine= InnoDB(設置InnoDB類型,另外還能夠設置MyISAM類型)設置建立數據庫及表默認存儲類型————————————————原文連接:https://blog.csdn.net/qq_36541478/article/details/84206512