1. 查找執行慢的SQL
Mysql查詢當前執行的sql
SELECT * FROM information schema.PROCESSLIST where info is not null;
Time列是sql持續的時間,單位是秒,越少越好,至少會有一條記錄,就是當前的監控sql。
Mysql查詢未提交事務中的歷史SQL
SELECT
ps.id 'PROCESS ID',
ps. USER,
ps. HOST,
esh.EVENT_ID,
trx.trx_started,
esh.event_name 'EVENT NAME',
esh.sql_text 'SQL',
ps.time
FROM
performance_schema.events_statements_history esh
JOIN performance_schema.threads th ON esh.thread_id = th.thread_id
JOIN information_schema.PROCESSLIST ps ON ps.id = th.processlist_id
LEFT JOIN information_schema.innodb_trx trx ON trx.trx_mysql_thread_id = ps.id
WHERE
ps.time > 60
AND trx.trx_id IS NOT NULL
AND ps. USER != 'SYSTEM_USER'
ORDER BY
esh.EVENT_ID;
當發現有鎖長期存在,影響別的事務,就需要本腳本
SQLServer查詢執行過的SQL
SELECT top 10
qs.total_worker_time / qs.execution_count / 1000 耗時
,st.text as sql_statement
,qs.creation_time as plan_last_compiled
,qs.last_execution_time as plan_last_executed
,qs.execution_count as plan_executed_count
,qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
order by plan_last_executed desc
沒有準‘實時’的抓取功能,只能是‘僞實時’
2. SQL 事務、鎖分析
select * from information_schema.`PROCESSLIST` where info is not NULL;
select * from information_schema.INNODB_TRX; -- 顯示掛起的事務
select * from information_schema.INNODB_LOCK_WAITS; -- 鎖等待
select * from information_schema.INNODB_LOCKS; -- 正在使用的鎖
SELECT * FROM information_schema.INNODB_TRX;
kill trx_mysql_thread_id;
3. 數據表信息收集
Mysql 單表信息收集,表的記錄數,及佔空間情況
SELECT TABLE_SCHEMA,TABLE_NAME,round((DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024,3) `size(GB)`,TABLE_ROWS FROM information_schema.tables
where table_name = 'vote_record'
SQLServer 單表信息收集
exec sp_spaceused '表名'
4.性能主意點
a. 使用連接Join來代替子查詢
查詢沒有子表信息的主表記錄
select * from employee where id not in (select empId from employeeInfo);
// 優化
select *
from employee e left join employeeInfo eInfo ON e.id = eInfo,empId
where eInfo.empId is null;
b. 使用索引的注意點
最好在相同類型的字段間進行比較
在建有所有的字段上儘量不要使用函數操作
select * from order where year(orderDate) < 2001;
select * from order where orderDate < '2001-01-1';
慎用like “%abc%” 這是以犧牲性能爲代價的
索引是可以多字段
Create index ix_date_emp on t_工作日誌表 (date, empid);
Create index ix_emp_date on t_工作日誌表 (empid, date);
Create index ix_date on t_工作日誌表 (date);
Create index ix_emp on t_工作日誌表 (empid);
c. 使用冗餘字段
記錄表,實例表等表結構,可以違反3NF,增加冗餘字段,比如保留操作人姓名,部門名稱,訂單總價等等。方便查詢
d. 減少一個SQL中JOIN 的個數
https://chenrenfei.github.io/sqltoy/#/