本文同時發表在https://github.com/zhangyachen/zhangyachen.github.io/issues/10html
SELECT thread_id FROM thread_5 WHERE id = 11074781 AND status = 0 AND thread_type = 0 ORDER BY post_time LIMIT 0, 50mysql
增長在id 、status、thread_type 、post_time上的4字段複合索引。git
緣由:經過優化先後的執行計劃對比可發現,優化後消除了filesort,直接利用索引的有序性避開額外的排序操做github
當不能使用索引生成排序結果的時候,MYSQL須要本身進行排序,若是數據量小則在內存中進行,若是數據量則須要使用磁盤,不過MYSQL將這個過程統一稱爲文件排序(filesort),即便徹底是內存排序不須要任何磁盤文件時也是如此。
若是須要排序的數據量小於排序緩衝區,MYSQL使用內存進行快速排序操做,若是內存不夠排序,那麼MYSQL會先將數據分塊,對獨立的塊使用快速排序進行排序,並將各個塊的排序結果放在磁盤上,而後將各個排序好的塊進行合併,最後返回排序結果。算法
MYSQL有2中排序算法:(再也不贅述2種排序的意思)
2次排序傳輸
單次排序傳輸sql
MYSQL在進行文件排序的時候須要使用的臨時存儲空間可能比想象的大許多。由於MYSQL在排序時,對每個排序記錄都會分配一個足夠長的定長空間來存放。這個定長空間必須足夠長以容納最長的字符串。數據庫
在關聯查詢的時候若是須要排序,MYSQL會分爲2中狀況來處理:若是order by子句的全部列都來自關聯的第一個表,那麼MYSQL在關聯處理第一個表的時候就進行文件排序,Explain的結果能夠看到Extra字段有using filesort。除此以外的狀況,MYSQL將關聯的結果放到一個臨時表中,而後在全部關聯結束以後,再進行文件排序。Extra的結果時using temporary;using filesort。若是有limit,也在排序以後應用,因此即便返回較少的數據,也會很是耗時。服務器
引用自:http://s.petrunia.net/blog/?p=24併發
SELECT c.cust_id cust_id FROM tb_aband_cust_contact c, tb_aband_phone p WHERE c.contact_id = contact_or_recipId AND p.full_phone=88123121 AND c.del_flag=0 AND p.flag=0 AND p.del_flag=0;函數
創建full_phone、flag、del_flag上的3字段複合索引
MYSQL一次查詢只能使用一個索引
DELETE FROM mydownload WHERE create_time<1271913480;
創建基於create_time的索引,並使用LIMIT修改成分批的執行,減小鎖的時間。
DELETE FROM mydownload WHERE create_time<1271913480 LIMIT 50000
刪除操做不會從新整理整個表,只是把行標記爲刪除,在表中留下「空洞」。
儘管MyISAM是表級鎖,可是依然能夠一邊讀取,一邊併發追加新行。這種狀況下只能讀取到查詢開始時的全部數據,新插入的數據時不可見的。這樣能夠避免不一致讀。
然而表中間的數據變更的話,仍是難以提供一致讀。MVCC是解決這個問題的最流行的辦法。但是MyISAM不支持MVCC,除非插入操做在表的末尾,不然不能支持併發插入。
經過配置concurrent_insert變量,能夠配置MyISAM打開併發插入
0:不容許併發插入,全部插入都會對錶加互斥鎖。
1:只要表中沒有空洞,MyISAM就容許併發插入
2:5.0及之後,強制插入到表的末尾,即便表中有空洞。若是沒有線程從表中讀取數據,MySQL將把新行放在空洞裏。
MyISAM存儲引擎的讀鎖和寫鎖是互斥的,讀寫操做是串行的。那麼,一個進程請求某個 MyISAM表的讀鎖,同時另外一個進程也請求同一表的寫鎖,MySQL如何處理呢?答案是寫進程先得到鎖。不只如此,即便讀請求先到鎖等待隊列,寫請求後 到,寫鎖也會插到讀鎖請求以前!這是由於MySQL認爲寫請求通常比讀請求要重要。
max_write_lock_count:
缺省狀況下,寫操做的優先級要高於讀操做的優先級,即使是先發送的讀請求,後發送的寫請求,此時也會優先處理寫請求,而後再處理讀請求。這就形成一個問題:一旦我發出若干個寫請求,就會堵塞全部的讀請求,直到寫請求全都處理完,纔有機會處理讀請求。此時能夠考慮使用max_write_lock_count:
max_write_lock_count=1
有了這樣的設置,當系統處理一個寫操做後,就會暫停寫操做,給讀操做執行的機會。
low-priority-updates:
咱們還能夠更乾脆點,直接下降寫操做的優先級,給讀操做更高的優先級。
low-priority-updates=1
http://www.cnblogs.com/coser/archive/2011/11/08/2241674.html
http://www.cnblogs.com/zhengyun_ustc/archive/2013/11/29/slowquery3.html
依賴子查詢
select_type爲DEPENDENT SUBQUERY,子查詢的第一個select依賴外部的查詢。
replace沒有保留舊值,而on duplicate key update相似於update,保留了舊值
http://www.path8.net/tn/archives/5613
http://blog.itpub.net/26250550/viewspace-1076292/
http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html
http://www.fromdual.com/mysql-handler-read-status-variables
我的理解:
Handler_read_first:從頭至尾掃描一個索引的次數
Handler_read_key:訪問索引的次數
Handler_read_last:從尾到頭掃描一個索引的次數
Handler_read_next:按照索引的順序讀取下一行次數,常常發生在範圍查找或者掃描索引的狀況中。
Handler_read_prev:按照索引的順序讀取前一行次數,常常發生在ORDER BY ... DESC
Handler_read_rnd:這個變量比較費解。。。,手冊中說:
The number of requests to read a row based on a fixed position. This value is high if you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.
全表掃描該值不會增長,不利用索引的排序也不會增長,只有在臨時表中進行排序該值纔會增長。
Handler_read_rnd_next:從數據文件中讀取下一行的次數。
最後兩個值應該越大越很差。
select user(),current_user()
user()函數會返回當前用戶鏈接到服務器使用的鏈接參數。
current_user()會返回從權限表中選擇的與訪問權限相關的用戶名和主機名對
user表排序工做以下,假定user表看起來像這樣:
+-----------+----------+-
| Host | User | …
+-----------+----------+-
| % | root | …
| % | jeffrey | …
| localhost | root | …
| localhost | | …
+-----------+----------+-
當服務器讀取表時,它首先以最具體的Host值排序。主機名和IP號是最具體的。'%'意味着「任何主機」而且是最不特定的。有相同Host值的條目首先以最具體的User值排序(空User值意味着「任何用戶」而且是最不特定的)。最終排序的user表看起來像這樣:
+-----------+----------+-
| Host | User | …
+-----------+----------+-
| localhost | root | … ...
| localhost | | … ...
| % | jeffrey | … ...
| % | root | … ...
+-----------+----------+-
當客戶端試圖鏈接時,服務器瀏覽排序的條目並使用找到的第一匹配。對於由jeffrey從localhost的鏈接,表內有兩個條目匹配:Host和User值爲'localhost'和''的條目,和值爲'%'和'jeffrey'的條目。'localhost'條目首先匹配,服務器可使用。
mysqld啓動時,全部受權表的內容被讀進內存而且今後時生效。
當服務器注意到受權表被改變了時,現存的客戶端鏈接有以下影響:
表和列權限在客戶端的下一次請求時生效。
數據庫權限改變在下一個USE db_name命令生效。
全局權限的改變和密碼改變在下一次客戶端鏈接時生效。
若是用GRANT、REVOKE或SET PASSWORD對受權表進行修改,服務器會注意到並當即從新將受權表載入內存。
若是你手動地修改受權表(使用INSERT、UPDATE或DELETE等等),你應該執行mysqladmin flush-privileges或mysqladmin reload告訴服務器再裝載受權表,不然你的更改將不會生效,除非你重啓服務器。
若是你直接更改了受權表但忘記重載,重啓服務器後你的更改方生效。這樣可能讓你迷惑爲何你的更改沒有什麼變化!
當你修改受權表的內容時,確保你按你想要的方式更改權限設置是一個好主意。要檢查給定帳戶的權限,使用SHOW GRANTS語句。例如,要檢查Host和User值分別爲pc84.example.com和bob的帳戶所授予的權限,應經過語句:
mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com';
一個有用的診斷工具是mysqlaccess腳本,由Carlier Yves 提供給MySQL分發。使用--help選項調用mysqlaccess查明它怎樣工做。注意:mysqlaccess僅用user、db和host表檢查存取。它不檢查tables_priv、columns_priv或procs_priv表中指定的表、列和程序級權限。
mysql> explain select * from recent_answer where id=7;
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
mysql實際訪問一遍primary key或者unique key(sql語句必須用到了primary key或者unique key),發現沒有這條記錄,返回Impossible WHERE noticed after reading const tables
沒有明確指出誰持有鎖,可是能夠顯示出事務在等待鎖
當前出現的鎖,可是沒法得出哪一個事務持有鎖,哪一個事務等待鎖
顯示哪一個事務持有鎖,哪一個事務等待鎖,可是沒法顯示正在阻塞中的事務的MySQL進程ID
能夠查看MySQL進程的ID
show engine innodb status
查找LATEST DETECTED DEADLOCK
關注WAITING FOR THIS LOCK TO BE GRANTED(事務在等待哪一個鎖)和HOLDS THIS LOCKS(阻塞事務的鎖的信息)
當事務開始時,它會獲取全部須要使用的表上的元數據鎖,並在事務結束後釋放鎖,全部其餘想要修改這些表定義的線程都須要等待事務結束。(5.5.3版本以後)
http://blog.itpub.net/26250550/viewspace-1071987/
翻譯自:http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html
插入的行數會被提早計算出來
例如:不包括嵌套子查詢的insert和replace
插入的行數不會被提早計算出來
例如:INSERT ... SELECT, REPLACE ... SELECT, LOAD DATA
包括:在插入時指定自增列的值
INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d'); //c1是自增列
INSERT ... ON DUPLICATE KEY UPDATE,可能分配給該語句的值沒有被用到(更新)
表鎖
「塊插入」使用表鎖。
簡單插入僅鎖定分配自增值的過程,一次性分配所需的數量
均不使用表鎖,僅鎖定分配自增值的過程。
僅能保證惟一而且單調自增,可是不保證連續。
可是可能會形成主從不一致。
http://dev.mysql.com/doc/refman/5.1/en/explain-extended.html
The filtered column indicates an estimated percentage of table rows that will be filtered by the table condition. That is, rows shows the estimated number of rows examined and rows × filtered / 100 shows the number of rows that will be joined with previous tables. Before MySQL 5.7.3, this column is displayed if you use EXPLAIN EXTENDED. As of MySQL 5.7.3, extended output is enabled by default and the EXTENDED keyword is unnecessry.
要想過濾掉A中的數據,必須使用where,即便on中包含有A表中的列的限制條件,也不會過濾A的任何數據
Created_tmp_disk_tables:在磁盤上創建臨時表的次數。若是沒法在內存上創建臨時表,MySQL則將臨時表創建到磁盤上。內存臨時表的最大值是tmp_table_size和max_heap_table_size values中偏小的那個。
Created_tmp_files:MySQL創建的臨時文件。
Created_tmp_tables:創建臨時表的數目。另外,每當執行 SHOW STATUS,都會使用一個內部的臨時表,Created_tmp_tables的全局值都會增長。
翻譯自:http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html
ICP應用的場合是當MySQL利用索引獲取表數據。在沒有ICP時,存儲引擎利用索引定位數據,將數據返回給服務器,在服務器端利用where條件過濾數據。當ICP啓用時,MySQL能夠在索引端利用where條件過濾不須要的數據,不須要在服務器端過濾。
MySQL只有當type值爲range、 ref、 eq_ref或者ref_or_null而且須要去表中取數據時纔會用到ICP(在MySQL5.6中分區表不能使用ICP,在5.7中修復)。當表是InnoDB時,索引必須是二級索引(一級索引能夠直接取數據,沒必要去表中取數據)
ICP是默認開啓的,經過設置optimizer_switch變量裏的index_condition_pushdown 標記來開啓ICP
mysql > set optimizer_switch=’index_condition_pushdown=on|off
假設有一張表,有以下索引:key(zipcode, lastname, firstname),sql語句以下:
SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';
若是沒有ICP,會在表中掃描全部zipcode='95054'的用戶,索引不會幫助過濾不符合lastname LIKE '%etrunia%'的行。當啓用ICP時,MySQL會在索引中過濾lastname LIKE '%etrunia%'的行(我的認爲能夠從explain的key_len字段看出來是否使用了lastname字段來過濾),減小了IO操做
取自http://s.petrunia.net/blog/?p=101 的一張圖,其實看了這張圖就知道ICP是幹嗎的了:
前臺線程的程序,必須等全部的前臺線程運行完畢後才能退出;然後臺線程的程序,只要前臺的線程都終止了,那麼後臺的線程就會自動結束並推出程序。
通常前臺線程用於須要長時間等待的任務,好比監聽客戶端的請求;後臺線程通常用於處理時間較短的任務,好比處理客戶端發過來的請求信息。
每個服務器端進程在該表中都有一行,代表是否啓用監控和歷史事件日誌
mysql> SELECT * FROM threads\G *************************** 1. row *************************** THREAD_ID: 1 NAME: thread/sql/main TYPE: BACKGROUND PROCESSLIST_ID: NULL PROCESSLIST_USER: NULL PROCESSLIST_HOST: NULL PROCESSLIST_DB: NULL PROCESSLIST_COMMAND: NULL PROCESSLIST_TIME: 80284 PROCESSLIST_STATE: NULL PROCESSLIST_INFO: NULL PARENT_THREAD_ID: NULL ROLE: NULL INSTRUMENTED: YES HISTORY: YES CONNECTION_TYPE: NULL THREAD_OS_ID: 489803 ... *************************** 4. row *************************** THREAD_ID: 51 NAME: thread/sql/one_connection TYPE: FOREGROUND PROCESSLIST_ID: 34 PROCESSLIST_USER: isabella PROCESSLIST_HOST: localhost PROCESSLIST_DB: performance_schema PROCESSLIST_COMMAND: Query PROCESSLIST_TIME: 0 PROCESSLIST_STATE: Sending data PROCESSLIST_INFO: SELECT * FROM threads PARENT_THREAD_ID: 1 ROLE: NULL INSTRUMENTED: YES HISTORY: YES CONNECTION_TYPE: SSL/TLS THREAD_OS_ID: 755399 ...
當Performance Schema庫初始化時,會將已經存在的線程填充到threads表中。從那以後,每當服務器新建立一個線程,就對應得在threads表中新增長一行。
在新建立的線程中,INSTRUMENTED和HISTORY列的值由setup_actors表決定。
當線程結束時,在threads表中對應的行將被移除。
和INFORMATION_SCHEMA.PROCESSLIST與SHOW PROCESSLIST的區別:
重要的字段:
其他字段的值看參考資料吧。
參考資料:http://dev.mysql.com/doc/refman/5.7/en/threads-table.html
setup_instruments存儲着一系列監控器對象,表明着什麼事件會被收集。(The setup_instruments table lists classes of instrumented objects for which events can be collected)
mysql> SELECT * FROM setup_instruments; +------------------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +------------------------------------------------------------+---------+-------+ ... | wait/synch/mutex/sql/LOCK_global_read_lock | YES | YES | | wait/synch/mutex/sql/LOCK_global_system_variables | YES | YES | | wait/synch/mutex/sql/LOCK_lock_db | YES | YES | | wait/synch/mutex/sql/LOCK_manager | YES | YES | ... | wait/synch/rwlock/sql/LOCK_grant | YES | YES | | wait/synch/rwlock/sql/LOGGER::LOCK_logger | YES | YES | | wait/synch/rwlock/sql/LOCK_sys_init_connect | YES | YES | | wait/synch/rwlock/sql/LOCK_sys_init_slave | YES | YES | ... | wait/io/file/sql/binlog | YES | YES | | wait/io/file/sql/binlog_index | YES | YES | | wait/io/file/sql/casetest | YES | YES | | wait/io/file/sql/dbopt | YES | YES | ...
每個在源碼中的監控器都會在表中有一行,即便該監控器代碼沒有被執行。當一個監控器代碼被啓用而且執行,就會創造一個監控器實例,在 *_instances表中可見。
參考資料:http://dev.mysql.com/doc/refman/5.7/en/setup-instruments-table.html
setup_consumers表用於配置事件的消費者類型,即收集的事件最終會寫入到哪些統計表中。(The setup_consumers table lists the types of consumers for which event information can be stored and which are enabled)
mysql> SELECT * FROM setup_consumers; +----------------------------------+---------+ | NAME | ENABLED | +----------------------------------+---------+ | events_stages_current | NO | | events_stages_history | NO | | events_stages_history_long | NO | | events_statements_current | YES | | events_statements_history | YES | | events_statements_history_long | NO | | events_transactions_current | NO | | events_transactions_history | NO | | events_transactions_history_long | NO | | events_waits_current | NO | | events_waits_history | NO | | events_waits_history_long | NO | | global_instrumentation | YES | | thread_instrumentation | YES | | statements_digest | YES | +----------------------------------+---------+
參考資料:http://dev.mysql.com/doc/refman/5.7/en/setup-consumers-table.html
http://www.cnblogs.com/cchust/p/5022148.html
setup_actors表決定着是否爲前臺進程(和客戶端鏈接有關的進程)開啓監控和歷史事件日誌。最多有100記錄,能夠經過修改performance_schema_setup_actors_size系統變量最大值。
mysql> SELECT * FROM setup_actors; +------+------+------+---------+---------+ | HOST | USER | ROLE | ENABLED | HISTORY | +------+------+------+---------+---------+ | % | % | % | YES | YES | +------+------+------+---------+---------+
對於每個前臺進程,會根據用戶名和主機名在setup_actors表中進行匹配。若是匹配成功,ENABLED和HISTORY列的值就會被分別賦給threads表中的INSTRUMENTED和HISTORY列。這可以讓用戶啓用監控器和歷史事件日誌。若是沒有在setup_actors表中匹配到,ENABLED和HISTORY列的值會被賦值爲NO。
對於setup_actors表的改變不會影響現有的線程,只會改變現有線程建立的子線程。若是想要改變現有的線程,改變threads表中對應行的 INSTRUMENTED和HISTORY的值。
參考資料:http://dev.mysql.com/doc/refman/5.7/en/setup-actors-table.html
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-instrument-naming.html
以下例子示例瞭如何像SHOW PROFILES和SHOW PROFILE同樣分析數據。
1.默認的,MySQL容許全部前臺線程監控和收集歷史事件。
mysql> SELECT * FROM setup_actors; +------+------+------+---------+---------+ | HOST | USER | ROLE | ENABLED | HISTORY | +------+------+------+---------+---------+ | % | % | % | YES | YES | +------+------+------+---------+---------+
能夠作以下改變:
mysql> UPDATE performance_schema.setup_actors SET ENABLED = 'NO', HISTORY = 'NO' -> WHERE HOST = '%' AND USER = '%'; mysql> INSERT INTO performance_schema.setup_actors (HOST,USER,ROLE,ENABLED,HISTORY) -> VALUES('localhost','test_user','%','YES','YES');
mysql> SELECT * FROM performance_schema.setup_actors; +-----------+-----------+------+---------+---------+ | HOST | USER | ROLE | ENABLED | HISTORY | +-----------+-----------+------+---------+---------+ | % | % | % | NO | NO | | localhost | test_user | % | YES | YES | +-----------+-----------+------+---------+---------+
2.確保statement and stage監控器在setup_instruments表中啓用。
mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' -> WHERE NAME LIKE '%statement/%'; mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' -> WHERE NAME LIKE '%stage/%';
3.確保events_statements_* 和events_stages_*啓用。
mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' -> WHERE NAME LIKE '%events_statements_%'; mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' -> WHERE NAME LIKE '%events_stages_%';
4.運行想要分析的語句:
mysql> SELECT * FROM employees.employees WHERE emp_no = 10001; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | +--------+------------+------------+-----------+--------+------------+
5.經過events_statements_history_long表肯定EVENT_ID
mysql> SELECT EVENT_ID, TRUNCATE(TIMER_WAIT/1000000000000,6) as Duration, SQL_TEXT -> FROM performance_schema.events_statements_history_long WHERE SQL_TEXT like '%10001%'; +----------+----------+--------------------------------------------------------+ | event_id | duration | sql_text | +----------+----------+--------------------------------------------------------+ | 31 | 0.028310 | SELECT * FROM employees.employees WHERE emp_no = 10001 | +----------+----------+--------------------------------------------------------+
6.一個語句極可能會觸發不少事件,這些事件都是循環嵌套的,每一個階段的事件記錄有一個nesting_event_id列,包含父表的event_id。(Query the events_stages_history_long table to retrieve the statement's stage events. Stages are linked to statements using event nesting. Each stage event record has a NESTING_EVENT_ID column that contains the EVENT_ID of the parent statement.
求翻譯,MLGB)
mysql> SELECT event_name AS Stage, TRUNCATE(TIMER_WAIT/1000000000000,6) AS Duration -> FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID=31; +--------------------------------+----------+ | Stage | Duration | +--------------------------------+----------+ | stage/sql/starting | 0.000080 | | stage/sql/checking permissions | 0.000005 | | stage/sql/Opening tables | 0.027759 | | stage/sql/init | 0.000052 | | stage/sql/System lock | 0.000009 | | stage/sql/optimizing | 0.000006 | | stage/sql/statistics | 0.000082 | | stage/sql/preparing | 0.000008 | | stage/sql/executing | 0.000000 | | stage/sql/Sending data | 0.000017 | | stage/sql/end | 0.000001 | | stage/sql/query end | 0.000004 | | stage/sql/closing tables | 0.000006 | | stage/sql/freeing items | 0.000272 | | stage/sql/cleaning up | 0.000001 | +--------------------------------+----------+ 15 rows in set (0.00 sec)
參考資料:http://dev.mysql.com/doc/refman/5.7/en/performance-schema-query-profiling.html
http://blog.51yip.com/mysql/1056.html
變長字段須要額外的2個字節,固定長度字段不須要額外的字節。而null都須要1個字節的額外空間,因此之前有個說法:索引字段最好不要爲NULL,由於NULL讓統計更加複雜,而且須要額外的存儲空間。這個結論在此獲得了證明。
key_len的長度計算公式:
varchr(10)變長字段且容許NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1) + 1(NULL) + 2(變長字段)
varchr(10)變長字段且不容許NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1) + 2(變長字段)
char(10)固定字段且容許NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1) + 1(NULL)
char(10)固定字段且容許NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1)
參考資料:http://www.ittang.com/2014/0612/13360.html
http://dev.mysql.com/doc/refman/5.7/en/dynindex-sysvar.html
http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html
http://www.cnblogs.com/rollenholt/p/3776923.html
http://blog.csdn.net/sxingming/article/details/52628531 http://blog.itpub.net/7728585/viewspace-2132521 http://blog.sina.com.cn/s/blog_4de07d5e01010jc4.html