mysql 分組查詢慢 乾掉mysql慢查詢

2021-10-18 10:04:11 字數 3908 閱讀 5651

主要思路

實時分析(show full processlist;)結合延後分析(mysql.slow_log),對sql語句進行優化

實時分析

檢視有哪些執行緒正在執行

2show processlist;

show full processlist;

-- 按照客戶端ip對當前連線使用者進行分組

select substring_index(host,':',1) as h,count(host) as c,user from information_schema.processlist group by h order by c desc,user;

-- 按使用者名稱對當前連線使用者進行分組

select substring_index(host,':',1) as h,count(host) as c,user from information_schema.processlist group by user order by c desc,user;

各種耗時sql對應的特徵改表copying to tmp table記憶體不夠用,轉成磁碟copying to tmp table on disk傳輸資料量大reading from net

sending data沒有索引copying to tmp table

sorting result

creating sort index

sorting result

延後分析

設定慢查詢引數

4slow_query_log 1

log_queries_not_using_indexes off

long_query_time 5

slow_query_log 1# 建資料庫

create table `slow_log_2019-05-30` (

`start_time` timestamp(6) not null default current_timestamp(6) on update current_timestamp(6),

`user_host` mediumtext not null,

`query_time` time(6) not null,

`lock_time` time(6) not null,

`rows_sent` int(11) not null,

`rows_examined` int(11) not null,

`db` varchar(512) not null,

`last_insert_id` int(11) not null,

`insert_id` int(11) not null,

`server_id` int(10) unsigned not null,

`sql_text` mediumtext not null,

`thread_id` bigint(21) unsigned not null,

key `idx_start_time` (`start_time`),

key `idx_query_time` (`query_time`),

key `idx_lock_time` (`lock_time`),

key `idx_rows_examined` (`rows_examined`)

) engine=innodb default charset=utf8mb4;

-- insert into slow_log.slow_log_2019-05-30 select * from mysql.slow_log;

-- truncate table mysql.slow_log ;

select * from slow_log.`slow_log_2019-05-30`

where sql_text not like '***`%'

order by query_time desc,query_time desc;

按優先順序排列,需要關注的列是lock_time,query_time,rows_examined.分析的時候應用二八法則,先找出最坑爹的那部分sql,率先優化掉,然後不斷not like或者刪除掉排除掉已經優化好的低效sql.

低效sql的優化思路

對於每乙個查詢,先用explain sql分析一遍,是比較明智的做法.

一般而言,rows越少越好,提防extra:using where這種情況,這種情況一般是掃全表,在資料量大(>10萬)的時候考慮增加索引.

慎用子查詢

盡力避免巢狀子查詢,使用索引來優化它們explain select *

from (

select *

from `s`.`t`

where status in (-15, -11)

limit 0, 10

) aorder by a.modified desc

比如說這種的,根本毫無必要.表面上看,比去掉子查詢更快一點,實際上是因為mysql 5.7對子查詢進行了優化,生成了derived table,把結果集做了一層快取.

按照實際的場景分析發現,status這個字段沒有做索引,導致查詢變成了全表掃瞄(using where),加了索引後,問題解決.

json型別

json資料型別,如果存入的json很長,讀取出來自然越慢.在實際場景中,首先要確定是否有使用這一型別的必要,其次,盡量只取所需欄位.

見過這樣寫的where j_a like '%"sid":514572%'

這種行為明顯是對mysql不熟悉,mysql是有json提取函式的.where json_extract(j_a, "$[0].sid")=514572;

雖然也是全表掃瞄,但怎麼說也比like全模糊查詢好吧?

更好的做法,是通過虛擬欄位建索引

但是現階段mysql對json的索引做的是不夠的,如果json資料列過大,建議還是存mongodb(見過把12萬json存mysql的,那讀取速度簡直無語).

字串型別where a=1

用數字給字串型別的字段賦值會導致該字段上的索引失效.where a='1'

分組查詢

group by,count(x),sum(x),慎用.非常消耗cpu

group byselect col_1 from table_a where (col_2 > 7 or mtsp_col_2 > 0) and col_3 = 1 group by col_1

這種不涉及聚合查詢(count(x),sum(x))的group by明顯就是不合理的,去重複查詢效果更高點select distinct(col_1) from table_a where (col_2 > 7 or mtsp_col_2 > 0) and col_3 = 1 limit ***;

count(x),sum(x)

x 這個字段最好帶索引,不然就算篩選條件有索引也會很慢

order by x

x這欄位最好帶上索引,不然show processlist;裡面可能會出現大量creating sort index的結果

組合索引失效

組合索引有個最左匹配原則key 'idx_a' (a,b,c)where b='' and c =''

這時組合索引是無效的.

其他explain sql

desc sql# innodb_trx表主要是包含了正在innodb引擎中執行的所有事務的資訊,包括waiting for a lock和running的事務

select * from information_schema.innodb_trx;

select * from information_schema.innodb_locks;

select * from information_schema.innodb_lock_waits;

參考鏈結

mysql 慢查詢 MySQL慢查詢

一 簡介 開啟慢查詢日誌,可以讓mysql記錄下查詢超過指定時間的語句,通過定位分析效能的瓶頸,才能更好的優化資料庫系統的效能。二 引數說明 slow query log 慢查詢開啟狀態 slow query log file 慢查詢日誌存放的位置 這個目錄需要mysql的執行帳號的可寫許可權,一般...

mysql配置慢查詢 MYSQL慢查詢配置

mysql慢查詢配置 1.慢查詢有什麼用?它能記錄下所有執行超過long query time時間的sql語句,幫你找到執行慢的sql,方便我們對這些sql進行優化.2.如何開啟慢查詢?首先我們先檢視mysql伺服器的慢查詢狀態是否開啟.執行如下命令 我們可以看到當前log slow queries...

mysql 慢查詢 測試 MySQL慢查詢測試實踐

1.開啟慢查詢的目的 開啟慢查詢日誌,可以讓mysql記錄下查詢超過指定時間的語句,通過定位分析效能的瓶頸,才能更好的優化資料庫系統的效能。2.設定mysql慢查詢 方法一 全域性變數設定 臨時生效 將 slow query log 全域性變數設定為 on 狀態 mysql set global s...