文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

分析SQL执行计划,需要关注哪些重要信息

2024-12-13 14:14

关注
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | t2    | NULL       | index | NULL          | idx_abc | 198     | NULL |    5 |    20.00 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+

一个执行计划中,共有 12 个字段,每个字段都十分重要。简单介绍这 12 个字段:

  1. id:执行计划中每个操作的独特标识符。对于一条查询语句,每个操作都有其唯一的 id。然而,在多表连接时,一次解释中的多个记录可能具有相同的 id。
  2. select_type:操作的种类。常见种类包括 SIMPLE、PRIMARY、SUBQUERY、UNION 等。不同种类的操作会影响查询的执行效率。
  3. table:当前操作所涉及的表。
  4. partitions:当前操作所涉及的分区。
  5. type:表示查询时所使用的索引类型,包括 ALL、index、range、ref、eq_ref、const 等。
  6. possible_keys:表示可能被查询优化器选择使用的索引。
  7. key:表示查询优化器选择使用的索引。
  8. key_len:表示索引的长度。索引的长度越短,查询时的效率越高。
  9. ref:用来表示哪些列或常量被用来与 key 列中命名的索引进行比较。
  10. rows:表示此操作需要扫描的行数,即扫描表中多少行才能得到结果。
  11. filtered:表示此操作过滤掉的行数占扫描行数的百分比。该值越大,表示查询结果越准确。
  12. Extra:表示其他额外的信息,包括 Using index、Using filesort、Using temporary 等。

假如我们有如下一张表(MySQL Innodb 5.7):

CREATE TABLE `t2` (
  `id` INT(11),
  `a` varchar(64) NOT NULL,
  `b` varchar(64) NOT NULL,
  `c` varchar(64) NOT NULL,
  `d` varchar(64) NOT NULL,
  `f` varchar(64) DEFAULT NULL,
  PRIMARY KEY(id),
  UNIQUE KEY `f` (`f`),
  KEY `idx_abc` (`a`,`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

首先,我们来分析几个重要字段的不同取值及其区别:

对于type字段,不同取值对查询性能有显著影响:

explain select * from t2 where f='Paidaxing';
explain select * from t1 join t2 on t1.id = t2.id where t1.f = 'P';
explain select * from t2 where a = 'Paidaxing';
explain select * from t2 where a > 'a' and a < 'c';
explain select c from t2 where b = 'P';
explain select * from t2 where d = "ni";

需要注意的是,以上类型由快到慢排列为:system > const > eq_ref > ref > range > index > ALL。

接下来我们来探讨两个常被忽略但十分重要的字段:

possible_keys 和 key 字段:

接着说一个很重要!的字段,但是经常被忽略的字段 extra,这个字段描述了 MySQL 在执行查询时所做的一些附加操作。下面是 Extra 可能的取值及其含义:

extra 字段:

explain select * from t2 where d = "ni";   # 非索引字段查询
explain select d from t2 where b = "ni"; # 未索引覆盖,用联合索引的非前导列查询
explain select b,c from t2 where a = "ni";  # 索引覆盖
explain select d from t2 where a = "ni" and b like "s%";   # 使用到索引下推。
explain select a from t2 where b = "ni";   # 索引覆盖,但是不符合最左前缀
 explain select b from t2 where a in ('a','d','sd');   # 索引覆盖,但是前导列是个范围
explain select * from t1 join t2 on t1.id = t2.id where a = 's';
explain select count(*),b  from t2 group by b;
explain select count(*),b  from t2 group by b;

课外补充

如何判断一条 SQL 走没有索引

首先看 key 字段有没有值,有值表示用到了索引树,但是具体是怎么用的,还得看 type 和 extra。

简单说以下几个情况:

情况一:

explain select b from t2 where a in ('a','d','sd');

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | index | NULL          | idx_abc | Using where; Using index |
+----+-------+---------------+----------+--------------------------+

type = index,key = idx_abc,extra = 使用 where;使用 index。这表明查询利用了 idx_abc 的联合索引,但未严格遵守最左前缀匹配,或者虽然遵守了最左前缀,但在 a 字段上进行了范围查询。因此,实际上仍需扫描索引树,效率并不理想。

情况二:

explain select * from t2 where a = 'Paidaxing';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | ref   | idx_abc      | idx_abc | NULL                     |
+----+-------+---------------+----------+--------------------------+

表示用到了索引进行查询,并且用到的是 idx_abc 这个非唯一索引。

情况三:

explain select * from t2 where f = 'f';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | const | f             | f        | NULL                     |
+----+-------+---------------+----------+--------------------------+

表示用到了索引进行查询,并且用到的是 f 这个唯一索引。

情况四:

explain select b,c from t2 where a = 'Paidaxing';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | ref   | idx_abc      | idx_abc |  Using index             |
+----+-------+---------------+----------+--------------------------+

表示用到了索引进行查询,并且用到了 idx_abc 这个索引,而且查询用到了覆盖索引,不需要回表。

情况五:

explain select b,c from t2 where d = 'Paidaxing';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | ALL   | NULL          | NULL     |  Using where             |
+----+-------+---------------+----------+--------------------------+

表示没有用到索引。

来源:码上遇见你内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯