Linux上慢SQL查询与优化
1. 收集慢查询日志:
- 确认慢查询日志开启:首先要确保数据库已经开启了慢查询日志功能。在 MySQL 中,可以通过查看配置文件(如
my.cnf
或my.ini
)中的相关配置参数来确认,或者使用SHOW VARIABLES LIKE 'slow_query_log';
命令查看慢查询日志是否开启以及日志文件的存储位置。如果没有开启,需要按照数据库的配置方法进行开启,并设置合适的查询时间阈值(例如,long_query_time
参数),超过该阈值的 SQL 语句会被记录到慢查询日志中。 - 获取慢查询日志文件:根据配置文件中指定的日志文件路径,找到慢查询日志文件。如果不确定文件路径,可以再次使用
SHOW VARIABLES LIKE 'slow_query_log_file';
命令来查看。
2.初步筛选和分类:
- 按时间排序:查看日志文件中记录的 SQL 语句的执行时间,按照时间从长到短进行排序,以便先关注那些执行时间最长、对系统性能影响最大的 SQL 语句。
- 按频率分类:有些 SQL 语句可能执行次数很多,但每次执行时间不一定很长;而有些语句可能执行次数较少,但每次执行都非常耗时。可以根据 SQL 语句在日志中出现的频率和总执行时间进行分类,以便分别进行分析。
3. 使用工具分析:
-
mysqldumpslow:这是 MySQL 自带的一个工具,用于分析慢查询日志。常用的命令选项如下:
-s
:用于指定排序方式,如c
(按照记录次数排序)、t
(按照时间排序)、l
(按照查询时间排序)、r
(按照返回的记录数排序);加上a
则表示相应的倒序,例如-sc
表示按照记录次数降序排列。
-t
:指定返回的记录条数,例如-t 10
表示返回前 10 条数据。
-g
:后面可以写一个正则匹配模式,用于筛选符合条件的 SQL 语句,大小写不敏感。例如,mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
可以查询出耗时最长的前 10 条语句,并按查询时间排序。 -
pt-query-digest:这是一个功能更强大的第三方工具,需要下载安装后使用。它可以对慢查询日志进行更详细的分析,常用的选项包括:
---create-review-table
:当使用--review
参数时,把分析结果输出到表中。
---create-history-table
:使用--history
参数,把分析结果输出到表中。
---filter
:对输入的慢查询按指定的字符串进行匹配过滤后再进行分析。
---limit
:限制输出结果的百分比或数量,默认值是 20,即将最慢的 20 条语句输出。
4. 分析 SQL 语句本身:
- 查看执行计划:使用
EXPLAIN
命令查看 SQL 语句的执行计划。EXPLAIN
会返回关于 MySQL 如何处理该语句的信息,包括如何连接表、以何种顺序连接表以及是否使用了索引等。重点关注type
、rows
、filtered
、extra
、key
等字段: type
:表示连接类型,性能从好到坏依次为system
>const
>eq_ref
>ref
>ref_or_null
>index_merge
>unique_subquery
>index_subquery
>range
>index
>all
。例如,all
表示全表扫描,通常性能较差,如果可能应尽量避免。rows
:表示 MySQL 估算要找到所需记录需要读取的行数,对于InnoDB
表,此数字是估计值。filtered
:是一个百分比的值,表示表中符合条件的记录数的比例。extra
:包含有关 MySQL 如何解析查询的其他信息,例如using filesort
(表示按文件排序,一般在指定的排序和索引排序不一致时出现)、using index
(表示是否使用了覆盖索引)、using temporary
(表示是否使用了临时表,性能较差,需要重点优化)、using where
(表示使用了WHERE
条件过滤)、using index condition
(MySQL 5.6 之后新增的索引下推,在存储引擎层进行数据过滤,减少回表的数据)等。key
:表示实际用到的索引,一般要结合possible_keys
列一起看,确认是否使用了预期的索引。- 检查索引使用情况:确认 SQL 语句中是否使用了合适的索引,以及索引是否有效。如果没有使用索引或者索引使用不当,可能会导致查询性能低下。例如,在条件查询中,如果字段没有建立索引,或者索引的选择性不高,都会影响查询效率。对于经常用于查询条件的字段,应该考虑建立索引;对于数据量较大的表,合理的索引设计尤为重要。
- 分析查询逻辑:检查 SQL 语句的查询逻辑是否合理。例如,是否存在不必要的子查询、复杂的连接操作或者过多的
OR
条件等。有时候,优化查询逻辑可以显著提高查询性能。例如,将复杂的OR
条件转换为UNION
操作,或者使用临时表来处理复杂的查询逻辑。 - 查看数据量和数据分布:了解相关表的数据量大小以及数据的分布情况。如果表中的数据量非常大,即使使用了索引,查询性能也可能受到影响。此时,可以考虑对表进行分区、分表或者数据归档等操作,以减少数据量。同时,数据的分布情况也会影响索引的使用效果,如果某些值在表中出现的频率非常高,索引的选择性可能会降低,从而影响查询性能。
5. 结合系统资源和性能指标分析:
- 查看系统资源使用情况:在分析慢查询日志时,还需要结合系统的资源使用情况,如 CPU、内存、磁盘 I/O 等。如果某个 SQL 语句执行时占用了大量的系统资源,可能是导致性能问题的原因之一。可以使用系统监控工具(如
top
、vmstat
、iostat
等)来查看系统资源的使用情况,确认是否存在资源瓶颈。 - 分析数据库连接和事务处理:检查数据库的连接数是否过多,以及事务的处理是否合理。过多的数据库连接会消耗系统资源,影响数据库的性能;而不合理的事务处理,如长时间持有事务、事务回滚等,也可能导致性能问题。可以通过数据库的监控工具或者查看数据库的日志来分析连接和事务的处理情况。
6. 记录和跟踪分析结果:
- 建立文档:将分析过程和结果记录下来,包括 SQL 语句、执行时间、分析过程中发现的问题以及优化建议等。这样可以方便后续的跟踪和参考,也有助于团队成员之间的交流和协作。
- 跟踪优化效果:在对 SQL 语句进行优化后,需要再次查看慢查询日志,确认优化后的效果。如果优化后的 SQL 语句仍然出现在慢查询日志中,或者性能没有明显提升,需要重新分析和优化。
7.如何优化慢sql:
-
使用索引:索引可以加快查询的速度。在频繁查询的列上创建索引,可以减少数据库的扫描次数,提高查询效率。
-
避免使用通配符:%:通配符在查询中会导致全表扫描,影响查询性能。尽量避免在查询条件中使用通配符。
-
避免使用子查询:子查询在一些情况下会导致性能问题,可以尝试使用连接或者其他方式来优化子查询。
-
使用合适的数据类型:选择合适的数据类型可以减少存储空间的占用,提高查询性能。
-
避免使用 SELECT *:只选择需要的列,不使用 SELECT * 可以减少数据的传输量,提高查询效率。
-
使用 LIMIT 来限制结果集大小:如果只需要查询部分结果,可以使用 LIMIT 来限制结果集的大小,减少传输数据的量。
-
使用 EXPLAIN 分析查询计划:使用 EXPLAIN 命令可以分析查询的执行计划,查看是否合理使用了索引。
-
将频繁执行的查询结果进行缓存:将频繁执行的查询结果缓存起来,可以减少对数据库的访问,提高查询性能。
原文地址:https://blog.csdn.net/qq_57473444/article/details/143810212
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!