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/#/