优化SQL语句的一般步骤

时间:2021-07-23 00:10:39

    当面对一个有SQL性能的数据库时,我们可以从以下步骤来对数据库进行分析。

1.通过show status命令了解各种SQL的执行频率

    MySQL客户端连接成功后,通过show [session | global] status命令可以提供服务器状态信息。session为当前连接的统计结果;global为数据库启动至今的统计结果;默认为session。
    以下为常用的统计参数:
    Com_select:执行select操作的次数,一次查询只累加1;
    Com_insert:执行insert操作的次数,对于批量插入的insert操作,只累加一次;
    Com_update:执行update操作的次数;
    Com_delete:执行delete操作的次数;
    以上是针对所有存储引擎的表操作都会进行累加。下面的参数只是针对InnoDB存储引擎的:
    Innodb_rows_read:select查询返回的行数;
    Innodb_rows_inserted:执行insert操作插入的行数;
    Innodb_rows_updated:执行update操作更新的行数;
    Innodb_rows_deleted:执行delete操作删除的行数;
    通过以上参数,可以了解当前数据库是以插入更新为主还是以查询为主,以及各种类型的SQL大致执行比例。对于更新操作的计数,是对执行次数的计数,不论提交还是回滚都会累加。
    对于事务型的应用,通过Com_commit和Com_rollback可以了解事务提交和回滚的情况,对于回滚操作非常频繁地数据库,可能意味着应用编写存在问题。
    以下参数便于用户了解数据库的基本情况:
    Connections:试图连接MySQL服务器的次数;
    Uptime:服务器工作时间;
    Slow_queries:慢查询的次数。

2.定位执行效率较低的SQL语句

    通过以下两种方式执行效率较低的SQL语句:
    1) 通过慢查询日志定位执行效率较低的SQL语句,用–log-slow-queries[=filename]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。
    2)慢查询日志在查询结束后才记录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题,可以使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时查看SQL的执行情况,同时对一些锁表操作进行优化。

3.通过explain分析低效SQL的执行计划

    查询到效率低的SQL语句后,可以通过explain或者desc命令获取MySQL如何执行select语句的信息,包括在select语句执行过程中表如何连接和连接的顺序。
    以下是explain语句返回参数:
    select_type:表示select的类型,常见的取值有SIMPLE(简单表,不使用表连接或子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个select)等。
    table:输出结果集的表。
    type:表示表的连接类型,性能由好到差的连接类型为system(表中仅有一行,即常量表)、const(单表中最多有一个匹配行,例如primary key或者unique index)、eq_ref(对于前面的每一行,在此表中只查询一条记录,简单来说就是多表连接中使用primary key或unique index)、ref(与eq_ref类似,但是使用普通的索引)、ref_or_null(与ref类似,区别在于条件中包含对NULL的查询)、index_merge(索引合并优化)、unique_subquery(in的后面是一个查询主键字段的子查询)、index_subquery(与unique_subquery类似,区别是在in后面是查询非唯一索引字段的子查询)、range(单表中范围查询)、index(对于前面的每一行,都通过查询索引来得到数据)、all(对于前面的每一行,都通过扫描全表来得到数据)。
    possible_keys:表示查询时,可能使用的索引。
    key:实际使用的索引
    key_len:索引字段的长度
    rows:扫描行的数量
    Extra:执行情况的说明和描述

4.确定问题并采取相应的优化措施

    通过explain语句得到的结果,我们可以确认问题出现的原因,采取相应的措施,进行优化提高执行的效率。