SQL優化
如何從一個大項目中,迅速的定位執行速度慢的語句. (定位慢查詢)
文件在:E:\學習文檔子目錄壓縮\數據庫\mysql\mysql優化\螞蟻\螞蟻1\1mysql優化之慢查詢日誌處理或 我的網盤\我的筆記\學習文檔子目錄壓縮\數據庫\mysql\mysql優化\螞蟻\螞蟻1\1mysql優化之慢查詢日誌處理
show status
使用show status使用show status查看MySQL服務器狀態信息
常用命令
--mysql數據庫啓動了多少時間 show status like 'uptime'; |
show stauts like 'com_select' show stauts like 'com_insert' ...類推 update delete(顯示數據庫的查詢,更新,添加,刪除的次數) |
show [session|global] status like .... 如果你不寫 [session|global] 默認是session 會話,指取出當前窗口的執行,如果你想看所有(從mysql 啓動到現在,則應該 global) |
//顯示到mysql數據庫的連接數 show status like 'connections '; |
//顯示慢查詢次數 show status like 'slow_queries'; |
慢查詢
什麼是慢查詢
MySQL默認10秒內沒有響應SQL結果,則爲慢查詢
可以去修改MySQL慢查詢默認時間
如何修改慢查詢
--查詢慢查詢時間 show variables like 'long_query_time'; --修改慢查詢時間 set long_query_time=1; ---但是重啓mysql之後,long_query_time依然是my.ini中的值 |
如何定位慢查詢
初始化測試數據
創建表結構
/*部門表*/ CREATE TABLE dept( deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*編號*/ dname VARCHAR(20) NOT NULL DEFAULT "", /*名稱*/ loc VARCHAR(13) NOT NULL DEFAULT "" /*地點*/ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; /*員工表*/ CREATE TABLE emp (empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*編號*/ ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/ job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/ mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上級編號*/ hiredate DATE NOT NULL,/*入職時間*/ sal DECIMAL(7,2) NOT NULL,/*薪水*/ comm DECIMAL(7,2) NOT NULL,/*紅利*/ deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部門編號*/ )ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
/*薪水*/ CREATE TABLE salgrade ( grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, losal DECIMAL(17,2) NOT NULL, hisal DECIMAL(17,2) NOT NULL )ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*測試數據*/
INSERT INTO salgrade VALUES (1,700,1200); INSERT INTO salgrade VALUES (2,1201,1400); INSERT INTO salgrade VALUES (3,1401,2000); INSERT INTO salgrade VALUES (4,2001,3000); INSERT INTO salgrade VALUES (5,3001,9999); |
創建函數
create function rand_string(n INT) returns varchar(255) #該函數會返回一個字符串 begin #chars_str定義一個變量 chars_str,類型是 varchar(100),默認值'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; declare chars_str varchar(100) default 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; declare return_str varchar(255) default ''; declare i int default 0; while i < n do set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1)); set i = i + 1; end while; return return_str; end
create FUNCTION rand_num() RETURNS int(5) BEGIN DECLARE i int default 0; set i =floor(10+RAND()*500); return i; END |
創建存儲過程
delimiter $$ create procedure insert_emp(in start int(10),in max_num int(10)) begin declare i int default 0; #set autocommit =0 把autocommit設置成0 set autocommit = 0; repeat set i = i + 1; insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num()); until i = max_num end repeat; commit; end $$ 執行存儲過程 call insert_emp (100001,4000000); |
如何將慢查詢定位到日誌中
在默認情況下,我們的mysql不會記錄慢查詢,需要在啓動mysql時候,指定記錄慢查詢纔可以
bin\mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定](安全模式啓動,數據庫將操作寫入日誌,以備恢復)
bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定]
先關閉mysql,再啓動, 如果啓用了慢查詢日誌,默認把這個文件放在
my.ini 文件中記錄的位置
#Path to the database root
datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
特別提醒,在安全模式啓動 即在cmd中執行mysql安裝目錄 bin\mysqld.exe --safe-mode --slow-query-log(5.5以上版本)或
bin\mysqld.exe –log-slow-queries=d:/abc.log
之前,必須先在 服務中關閉mysql
總體步驟
1.建測試數據庫,造400萬僞數據(按上面步驟,建表,建函數,建存儲過程,執行存儲過程即可)
2. 在mysql安裝文件中從my.ini從查出日誌文件所在位置(datadir),刪除原有日誌文件如ib_logfile0等,然後先在服務中關閉mysql(一定要右鍵屬性,停止,看到啓動已經亮了纔行),然後cmd mysql安全模式啓動
注意 5.0的版本bin下只有 mysqld-nt.exe命令和5.8的mysqld.exe是一個意思,cmd看到如下表示安全模式已經成功
3.navicte中連接測試數據庫,修改將MySQL默認10秒內(修改爲1秒) 沒有響應SQL結果,則爲慢查詢
--修改慢查詢時間
set long_query_time=1; ---但是重啓mysql之後,long_query_time依然是my.ini中的值
4. 執行如下慢查詢語句,查400萬數據 select * from emp;
show status like 'slow_queries';--顯示慢查詢次數
5.在 datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"(my.ini從查出日誌文件所在位置(datadir))
或abc.log 去看那條慢查詢sql
慢查詢日誌文件爲:PC-20190414IHSY-slow.log
bin\mysqld.exe, Version: 5.5.62-log (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: (null)
Time Id Command Argument
# Time: 190929 17:59:28
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 6.909395 Lock_time: 0.000000 Rows_sent: 6679074 Rows_examined: 6679074
use yh;
SET timestamp=1569751168;
select * from emp;
可以看到 Query_time: 6.909395 查詢時間爲6.9秒 ,慢查詢sql爲select * from emp;
--修改慢查詢時間
set long_query_time=1; ---但是重啓mysql之後,long_query_time依然是my.ini中的值
show status like 'slow_queries';--顯示慢查詢次數