乐趣区

关于java:搞定面试官-可以讲一下你平时是如何进行-SQL-性能分析的嘛

SQL 性能剖析

大家好,我是程序员啊粥,这段时间始终在分享 MySQL 索引系列的文章,咱们学会了 B + 树索引模型,以及索引长度的计算、明明应用 Delete 把数据删除了,然而为什么磁盘上的数据文件大小没变?等内容,明天开始咱们学习 SQL 的优化。

说起 SQL 优化,咱们须要晓得一个 SQL 的执行频率,如果说你有一条慢 SQL,好几个月才执行一次,那我感觉你其实也没啥破费精力优化它的必要,毕竟执行频率太低,投入产出比有余。

SQL 执行频率

对于查问 SQL 执行频率,咱们能够应用 show global status like 'Com___',(这后边是 7 个下划线), 这条命令能够显示以后数据库中增删改查等各个语句的应用次数,能够看我,我这个库中,大量的执行语句都是 select 语句,其余语句非常少。

那阐明这个库中的查问时比拟多的,所以咱们须要额定关注查问的效率。

对于具体的查问效率,咱们能够通过查询数据库的慢 SQL 日志来查问。

慢查问日志

  • 慢查问日志是否开启:show variables like 'slow_query_log'
  • 开启慢日志:set global slow_query_log = 1;(只对以后会话失效,全局失效须要批改 my.conf 配置文件)
  • 设置慢查问阈值:set global long_query_time = 4
  • 之后就能够在 slow.log 文件中查问到执行的慢 SQL。

这部分根本把握这几个命令就能够了,咱们能够在长期会话中开启慢 SQL 日志,而后执行对应的 SQL 语句来记录日志。

慢查问日志能够帮咱们记录具体的慢查问语句,然而为什么慢它是没发通知咱们的,因而,咱们还须要借助其余的一些命令来帮忙咱们具体慢的起因。

应用 MySQL profiling 性能分析单条查问

  • show profiles 能在做 SQL 优化时帮忙咱们理解耗时具体耗在了哪里。
  • show prifile for query id 查看具体各个阶段的耗时

这两条命令联合在一起,能够明确通知咱们这条 SQL 在执行中,到底耗时在那一步,比方是某个子查问或者 Server 层数据传输等具体起因。

得出工夫耗费在那个环节之后,咱们便能够应用具体的执行打算来进行针对性的优化,下边着重介绍一下对于 SQL 执行打算的应用。

explain 执行打算

后果输入展现:

id

该语句的惟一标识。如果 explain 的后果包含多个 id 值,则数字越大越先执行;而对于雷同 id 的行,则示意从上往下顺次执行。

select_type

查问类型,有如下几种取值:

table

示意以后这一行正在拜访哪张表,如果 SQL 定义了别名,则展现表的别名

partitions

以后查问匹配记录的分区。对于未分区的表,返回 null

type

连贯类型,有如下几种取值, 性能从好到坏排序 如下:

  • system:该表只有一行(相当于零碎表),system 是 const 类型的特例
  • const:针对主键或惟一索引的等值查问扫描, 最多只返回一行数据. const 查问速度十分快, 因为它仅仅读取一次即可
  • eq_ref:当应用了索引的全副组成部分,并且索引是 PRIMARY KEY 或 UNIQUE NOT NULL 才会应用该类型,性能仅次于 system 及 const。
  • ref:当满足索引的最左前缀规定,或者索引不是主键也不是惟一索引时才会产生。如果应用的索引只会匹配到大量的行,性能也是不错的。
  • fulltext:全文索引
  • ref_or_null:该类型相似于 ref,然而 MySQL 会额定搜寻哪些行蕴含了 NULL。这种类型常见于解析子查问
  • index_merge:此类型示意应用了索引合并优化,示意一个查问外面用到了多个索引
  • unique_subquery:该类型和 eq_ref 相似,然而应用了 IN 查问,且子查问是主键或者惟一索引。
  • index_subquery:和 unique_subquery 相似,只是子查问应用的是非惟一索引
  • range:范畴扫描,示意检索了指定范畴的行,次要用于有限度的索引扫描。比拟常见的范畴扫描是带有 BETWEEN 子句或 WHERE 子 句里有 >、>=、<、<=、IS NULL、<=>、BETWEEN、LIKE、IN() 等操作符。
  • index:全索引扫描,和 ALL 相似,只不过 index 是全盘扫描了索引的数据。当查问仅应用索引中的一部分列时,可应用此类型。有两种场景会触发:

    • 如果索引是查问的笼罩索引,并且索引查问的数据就能够满足查问中所需的所有数据,则只扫描索引树。此时,explain 的 Extra 列的后果是 Using index。index 通常比 ALL 快,因为索引的大小通常小于表数据。
    • 按索引的程序来查找数据行,执行了全表扫描。此时,explain 的 Extra 列的后果不会呈现 Uses index。
  • ALL:全表扫描,性能最差。

possible_keys

展现以后查问能够应用哪些索引,这一列的数据是在优化过程的晚期创立的,因而有些索引可能对于后续优化过程是没用的。

key

示意 MySQL 理论抉择的索引

key_len

索引应用的字节数。因为存储格局,当字段容许为 NULL 时,key_len 比不容许为空时大 1 字节。

ref

示意将哪个字段或常量和 key 列所应用的字段进行比拟。

如果 ref 是一个函数,则应用的值是函数的后果。要想查看是哪个函数,可在 EXPLAIN 语句之后紧跟一个 SHOW WARNING 语句。

rows

MySQL 估算会扫描的行数,数值越小越好。

filtered

示意合乎查问条件的数据百分比,最大 100。用 rows × filtered 可取得和下一张表连贯的行数。例如 rows = 1000,filtered = 50%,则和下一张表连贯的行数是 500。

以上就是对于 explain 执行打算后果中的字段阐明,具体的含意很多都是我从官网间接拿过去的,比拟干燥,当然也不须要你死记硬背,只有你在 SQL 优化过程中,无意识的应用 explain 剖析它的执行打算,而后来查阅一下每个字段是什么含意,最初针对具体的问题进行能进行优化,这就能够了。

对于 explain 的具体应用,我会在下一篇文章中进行实战演练,明天就单纯介绍一下这些字段的含意,你有个大略印象就能够。

退出移动版