使用EXPLAIN關鍵字能夠模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理SQL語句的。分析查詢語句或是表結構的性能瓶頸。html
EXPLAIN + SQL語句
+----+-------------+-------------+------+---------------+------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------+------+---------------+------+---------+------+------+-------+
<1>、id: select查詢的序列號,包含一組數字,表示查詢中執行select子句或操做表的順序python
<2>、select_type:分別用來表示查詢的類型,主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢。mysql
<3>、table:指的就是當前執行的表sql
<4>、type:顯示的是查詢使用了哪一種類型數據庫
從最好到最差依次是:system > const > eq_ref > ref > range > index > all。通常來講,得保證查詢至少達到range級別,最好能達到ref。vim
<5>、possible_keys:顯示可能應用在這張表中的索引,一個或多個。查詢涉及到的字段上若存在索引,則該索引將被列出,但不必定被查詢實際使用。服務器
<6>、key:實際使用的索引,若是爲NULL,則沒有使用索引。(可能緣由包括沒有創建索引或索引失效)。查詢中若使用了覆蓋索引(select 後要查詢的字段恰好和建立的索引字段徹底相同),則該索引僅出如今key列表中。性能
<7>、key_len:表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度,在不損失精確性的狀況下,長度越短越好。key_len顯示的值爲索引字段的最大可能長度,並不是實際使用長度,即key_len是根據表定義計算而得,不是經過表內檢索出的。測試
<8>、ref:顯示索引的那一列被使用了,若是可能的話,最好是一個常數。哪些列或常量被用於查找索引列上的值。優化
<9>、rows:根據表統計信息及索引選用狀況,大體估算出找到所需的記錄所須要讀取的行數,也就是說,用的越少越好。
<10>、包含不適合在其餘列中顯式但十分重要的額外信息。
關於 explain 命令的具體用法和字段含義能夠參考官網explain-output。
須要強調 rows 是核心指標,絕大部分 rows 小的語句執行必定很快(也有例外)。因此優化語句基本上都是在優化rows。
執行計劃:讓mysql預估執行操做(通常正確) all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const id,email 慢: select * from test where name='cai' explain select * from test where name='cai' type: ALL(全表掃描) select * from test limit 1; 快: select * from test where email='cai@' type: const(走索引)
0.先運行看看是否真的很慢,注意設置 SQL_NO_CACHE 1.where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單表每一個字段分別查詢,看哪一個字段的區分度最高 2.explain查看執行計劃,是否與1預期一致(從鎖定記錄較少的表開始查詢) 3.order by limit 形式的sql語句讓排序的表優先查 4.瞭解業務方使用場景 5.加索引時參照建索引的幾大原則 6.觀察結果,不符合預期繼續從0分析
MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。long_query_time的默認值爲10,意思是運行10S以上的語句。默認狀況下,Mysql數據庫並不啓動慢查詢日誌,須要手動來設置這個參數,固然,若是不是調優須要的話,通常不建議啓動該參數,由於開啓慢查詢日誌會或多或少帶來必定的性能影響。慢查詢日誌支持將日誌記錄寫入文件,也支持將日誌記錄寫入數據庫表。
# 慢日誌 - 執行時間 > 10 - 未命中索引 - 日誌文件路徑 # 配置: - 內存 show variables like '%query%'; show variables like '%queries%'; set global 變量名 = 值 - 配置文件 mysqld --defaults-file='E:\cai\mysql-5.7.16-winx64\mysql-5.7.16-winx64\my-default.ini' # my.conf內容: slow_query_log = ON slow_query_log_file = D:/.... # 注意:修改配置文件以後,須要重啓服務
#======================================================== 錯誤日誌: 記錄 MySQL 服務器啓動、關閉及運行錯誤等信息 二進制日誌: 又稱binlog日誌,以二進制文件的方式記錄數據庫中除 SELECT 之外的操做 查詢日誌: 記錄查詢的信息 慢查詢日誌: 記錄執行時間超過指定時間的操做 中繼日誌: 備庫將主庫的二進制日誌複製到本身的中繼日誌中,從而在本地進行重放 通用日誌: 審計哪一個帳號、在哪一個時段、作了哪些事件 事務日誌或稱redo日誌: 記錄Innodb事務相關的如事務執行時間、檢查點等 #========================================================
## 1、bin-log 1. 啓用 # vim /etc/my.cnf [mysqld] log-bin[=dir\[filename]] # service mysqld restart 2. 暫停 //僅當前會話 SET SQL_LOG_BIN=0; SET SQL_LOG_BIN=1; 3. 查看 查看所有: # mysqlbinlog mysql.000002 按時間: # mysqlbinlog mysql.000002 --start-datetime="2012-12-05 10:02:56" # mysqlbinlog mysql.000002 --stop-datetime="2012-12-05 11:02:54" # mysqlbinlog mysql.000002 --start-datetime="2012-12-05 10:02:56" --stop-datetime="2012-12-05 11:02:54" 按字節數: # mysqlbinlog mysql.000002 --start-position=260 # mysqlbinlog mysql.000002 --stop-position=260 # mysqlbinlog mysql.000002 --start-position=260 --stop-position=930 4. 截斷bin-log(產生新的bin-log文件) a. 重啓mysql服務器 b. # mysql -uroot -p123 -e 'flush logs' 5. 刪除bin-log文件 # mysql -uroot -p123 -e 'reset master' ## 2、查詢日誌 啓用通用查詢日誌 # vim /etc/my.cnf [mysqld] log[=dir\[filename]] # service mysqld restart ## 3、慢查詢日誌 啓用慢查詢日誌 # vim /etc/my.cnf [mysqld] log-slow-queries[=dir\[filename]] long_query_time=n # service mysqld restart MySQL 5.6: slow-query-log=1 slow-query-log-file=slow.log long_query_time=3 單位爲秒 查看慢查詢日誌 測試:BENCHMARK(count,expr) SELECT BENCHMARK(50000000,2*3);