在SQL性能优化过程中,经常遇到的问题包括查询响应时间过长、数据库负载过高、不适当的索引策略以及查询语句的复杂性等。
SQL性能分析可以帮助我们发现潜在的性能问题,定位瓶颈所在,并提供相应的优化策略。通过深入分析SQL查询的执行计划、监控关键性能指标以及使用专业的性能分析工具,我们可以及时优化和改进数据库应用程序的性能。
通过指定DQL语句(Data Query Language),可以查看某个数据库所有增删改查的次数。从而分析这个数据库在增删改查的操作中,哪几种操作的比例大。
使用以下命令进行查询:Com后面跟了7个下划线,表示查找Com后面跟了7个字符的属性和属性值
show global status like 'Com_______';
下图数据可以看出,select操作明显是最多的,其次是更新操作。
慢SQL对数据库性能、应用程序响应时间和系统可用性都会产生很大影响,找出慢SQL是优化和改善数据库性能的开始。
定位哪些sql语句执行效率低(默认超过10秒),会自动存储到日志中,方便分析。
慢查询日志是默认关闭的,查看日志前要检查MySQL是否启用:
SHOW VARIABLES LIKE 'slow_query_log';
先说为什么Mysql默认不开启慢查询日志,想必是有开发者的考量。开启日志后会造成的影响:
性能开销:记录每个查询的执行时间等信息需要额外的系统资源,包括磁盘IO和CPU时间。对于高负载的生产环境,可能会对数据库性能产生显著的影响。
磁盘空间消耗:日志不加管理会占用大量的磁盘空间,需要定期进行管理和维护。
我们可以手动启用慢查询日志,并根据实际需求进行配置和管理。
需要进到服务器修改配置文件,通常位置是:
Linux:/etc/mysql/my.cnf
Windows:C:\ProgramData\MySQL\MySQL Server X.X\my.ini
进入配置文件,输入以下命令查找指定配置
/[mysqld]
在[mysqld]部分中添加或修改以下行(如果已存在则修改):
slow_query_log = 1 // 启用慢查询日志
long_query_time = 2 // 定义查询执行时间的阈值,单位为秒。这里设置为2秒,可以根据需要进行调整。
修改完毕后保存并关闭配置文件,重启MySQL服务,以使更改生效。
SHOW VARIABLES LIKE 'slow_query_log_file';
show profiles命令是MySQL中的一个诊断命令,用于显示执行过的语句或连接的性能分析信息。可以获取有关特定查询或连接的详细性能统计数据,以便进行性能分析和优化。
show profiles命令显示的是当前会话(当前数据库连接)中最近执行的SQL语句的性能分析信息。每次执行SQL语句后,相关的性能分析信息会被记录并保留在当前会话中,直到会话结束或重新启动。
profiling默认是关闭的,可以通过set语句开启
SET profiling=1;
##查看是否开启
SELECT @@have_profiling;
执行一系列的业务sql的操作,然后通过以下命令查看执行耗时:
show profiles;
show profile for query xxxxx;
show profile cpu for query xxxxx;
在查询语句前加上关键字explain,就可以监测到该语句执行过程中表的连接情况和顺序、是否用到了索引等信息。例如:
## 专门找了个复杂点的SQL举例
explain select orguser.organization_name,orguser.id organization_id ,count(*) allnum
from tid_alarm_detail ad
right join (
select org.organization_name,org.id,user_id
from tc_organization_user
right join(
select SUBSTRING(organization_name,5,3) organization_name ,id
from tc_organization
WHERE organization_name like '_年级%' and organization_name!='四年级(14期)' and is_delete =0
union
select SUBSTRING(organization_name,1,3),id
from tc_organization
WHERE organization_name like '__期___' and is_delete=0
)org
on tc_organization_user.organization_id=org.id
WHERE is_delete=0
)orguser
on ad.user_jifen_id = orguser.user_id and ad.orgazition=orguser.id
where is_delete=0
and remark is not null
AND create_time like (SELECT CONCAT(DATE_FORMAT(NOW(), '%Y-%m'),"%"))
GROUP BY organization_name