mysql 慢查詢


1. 慢查詢日志的打開
正常情況下,只需要在配置文件中增加slow_query_log = 1配置,即打開慢查詢日志,未指定slow_query_log_file的情況下,會自動生成一個以主機名+‘slow’.log 的文件。
show variables like '%slow_query%'

2. 默認情況下記錄慢查詢的時間閾值為10s
show variables like '%long_query_time%'
--long_query_time 指定超過多少時長的查詢需要被記錄;

show variables like '%log_output%'

show variables like '%min_examined_row_limit%';
--min_examined_row_limit 超過指定行數的掃描查詢開關;默認0,代表不限制掃描函數;

方式一設置開啟MySQL慢日志參數:無需重啟即可生效,但是重啟會導致設置失效
set global long_query_time=0.1;
set global log_queries_not_using_indexes=on;
set global slow_query_log = on;
set log_output = 'FILE,TABLE';

方式二需要修改配置文件 my.ini /my.cnf 配置文件中配置:需要重啟 MySQL 才可以生效,命令為 service mysqld restart
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow_query_log_202123.log
log_output = table
long_query_time = 1

可以將慢查詢日志同時記錄在文件以及 mysql.slow_log

查詢慢查詢日志:select * from mysql.slow_log
select CONVERT(sql_text USING utf8) sql_text from mysql.slow_log;

start_time 為執行時間,user_host 為用戶的主機名,query_time 為查詢所花費的時間,
lock_time 為該查詢使用鎖的時間,rows_sent 為這條查詢返回了多少數據給客戶端,
rows_examined 表示這條語句掃描了多少行,db 為數據庫,sql_text 為這條 SQL,
thread_id 為執行這條查詢的線程 id。

查詢慢sql 日志文件保存在哪里:show variables like '%slow_query_log_file%'

沒有index的查詢記錄開關
show global variables like '%indexes%';

log_queries_not_using_indexes 是否開啟記錄沒有index 的查詢;
log_throttle_queries_not_using_index 做日志記錄的流量控制,一分鍾可以記錄多少條;默認 0 是不限制;

***********explain / desc
MySQL中執行explain或者desc命令查看慢查詢語句,可以看出為什么SQL查詢慢。如:

explain select * from dbname.tableName

desc select * from dbname.tableName

它的輸出格式細節可以關注MySQL explain format,在輸出中最要注意的是:
1. type 字段值:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery >
index_subquery > range > index > all
備注:ALL是效率最差;若type 值為 index 或 all,則需要優化
2.Extra 字段值:出現 Using filesort 以及 Using temporary,表示mysql 根本不能使用索引,效率會受到重大影響。應盡可能對此進行優化;
最主要是要關注在orderby和groupby。
Using filesort:表示mysql 會對結果使用一個外部索引排序,而不是從表里按索引次序讀到相關內容。
Using temporary:表示mysql 對查詢結果排序時使用臨時表;常見於 order by 和 group by。

3. key:是否有使用Key,key長度如何


Note: SQL優化是個很復雜的過程,有可能出現拆東牆補西牆的情況:
比如給數據庫表加入了索引之后,確實查詢快了,可是存儲空間加多了,插入刪除操作耗時也增加了;
如果在一個寫多讀少的系統中,執行這種優化可能會起到反效果。
所以優化完之后千萬不能大意,要持續監控系統,防止出現引入新瓶頸的情況。


******Mysql慢查詢優化方法及優化原則 來自:https://www.jb51.net/article/161441.htm
1、日期大小的比較,傳到xml中的日期格式要符合'yyyy-MM-dd',這樣才能走索引,如:'yyyy'改為'yyyy-MM-dd','yyyy-MM'改為'yyyy-MM-dd'【這樣MYSQL會轉換為日期類型】

2、條件語句中無論是等於、還是大於小於,WHERE左側的條件查詢字段不要使用函數或表達式或數學運算

3、WHERE條件語句嘗試着調整字段的順序提升查詢速度,如把索引字段放在最前面、把查詢命中率高的字段置前等

4、保證優化SQL前后其查詢結果是一致的

5、在查詢的時候通過將EXPLAIN命令寫在查詢語句前,測試語句是否有走索引【具體用法百度】

6、禁止使用SELECT * FROM操作,應只返回需要的字段,不需要的字段不要返回

7、可以嘗試分解復雜的查詢,在應用層面進行表關聯,以此代替SQL層面的表關聯

8、WHERE子句和ORDER BY子句涉及到的列建索引

9、避免在WHERE子句中對字段進行NULL判斷【可以對表字段改造一下,字符串型字段默認值設置為空字符串,數字型字段默認值設置為0,日期型字段默認值設置為1990-01-01等】

10、避免在WHERE子句中使用!=或<>操作符

11、避免在WHERE子句中使用OR操作符

12、BETWEEN AND代替IN

13、LIKE '%abc%'不會走索引,而LIKE 'abc%'會走索引

14、避免對字段進行表達式操作

15、避免對字段進行函數操作

16、GROUP BY操作默認會對GROUP BY后面的字段進行排序,如果你的程序不需要排序,可在GROUP BY語句后面加上ORDER BY NULL去除排序

17、如果是數值型字段,則盡量設計為數值型字段,不要為了方便、為了偷懶而給后面維護的同事埋坑

18、表中所有字段設計為NOT NULL

19、返回條數固定時,用LIMIT語句限制返回記錄的條數,如只需要一條記錄,或肯定只有一條記錄符合條件,那建議加上LIMIT 1

20、對於枚舉類型的字段【即有固定羅列值的字段】,建議使用ENUM而不是VARCHAR,如性別、星期、類型、類別等

21、對於存IP地址的字段設計為成UNSIGNED INT型

22、避免在SQL中使用NOW()、CURDATE()、RAND()函數【因為這種方式會導致MYSQL無法使用SQL緩存】,可以轉化為通過傳入參數的方式

23、對於統計類的查詢【如查詢連續幾個月的數據總量,或查詢同比、環比等】,可以通過定時查詢並統計到統計表的方式提高查詢速度

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM