当前位置: 首页 > 面试题库 >

如何基于EXPLAIN计划优化MySQL查询

松俊才
2023-03-14
问题内容

从查询EXPLAIN计划来看,如何确定最能在哪里进行优化?

我很欣赏要检查的第一件事是是否使用了良好的索引,但是除此之外,我有些困惑。通过过去的反复试验,我有时发现执行连接的顺序可以很好地改进,但是从执行计划中如何确定呢?

尽管我非常想对如何优化查询有一个很好的一般理解(建议多加赞赏!),但我也意识到,讨论具体案例通常比抽象讨论要容易得多。由于我目前正在用这个把头撞在墙上,因此您的想法将不胜感激:

id select_type表的类型possible_keys键key_len参考行额外
 1 SIMPLE S const PRIMARY,l,p,f4 PRIMARY 2 const 1使用临时
 1 SIMPLE Q ref PRIMARY,SS 2 const 204使用索引
 1 SIMPLE V ref PRIMARY,n,QQ 5 const,db.Q.QID 6使用位置; 使用索引;不同
 1 SIMPLE R1 ref PRIMARY,LL 154 const,db.V.VID 447使用索引; 不同
 1 SIMPLE W eq_ref PRIMARY,w PRIMARY 5 const,db.R.RID,const 1使用位置; 不同
 1 SIMPLE R2 eq_ref PRIMARY,L PRIMARY 156 const,db.W.RID,const 1使用位置; 不同

我对执行计划的最后一行的解释是否正确,如下所示:

  • 由于它在主键上完全匹配,因此R2每个输出行只需要获取一行;
  • 但是,然后根据适用于R2?的某些条件过滤此类输出行。

如果是这样,我的问题就在于在最后一步中进行的过滤。如果条件导致没有过滤(例如WHERECol_1_to_3IN (1,2,3)),则查询将非常快地运行(〜50ms);但是,如果条件限制了选择的行(WHERECol_1_to_3IN (1,2)),则查询将花费更长的时间(〜5s)。如果限制为单个匹配(WHERECol_1_to_3IN (1)),则优化程序会建议使用完全不同的执行计划(执行计划略优于5s,但仍比50ms差很多)。似乎没有一个更好的索引可以在该表上使用(假设已经完全使用主键为每个结果返回一行?)。

一个人应该如何解释所有这些信息?我猜对了吗,因为要在要连接的最终表上进行这种输出过滤,所以与早先连接表并更快地过滤此类行相比,浪费了大量的精力?如果是这样,如何确定执行计划中的什么时候R2应该加入?

虽然我拒绝在此处完整地包含查询和架构(因为我真的很可能知道要查找的内容,而不仅仅是被告知答案),但我知道有必要推进讨论:

SELECT DISTINCT
    `Q`.`QID`
FROM
    `S`
    NATURAL JOIN `Q`
    NATURAL JOIN `V`
    NATURAL JOIN `R` AS `R1`
    NATURAL JOIN `W`

    JOIN `R` AS `R2` ON (
            `R2`.`SID` = `S`.`SID`
        AND `R2`.`RID` = `R1`.`RID`
        AND `R2`.`VID` = `S`.`V_id`
        AND `R2`.`Col_1_to_3` IN (1,2) -- this is where performance suffers!
    )

WHERE
    AND `S`.`SID` = @x
    AND `W`.`WID` = @y
;

该表的定义R是:

CREATE TABLE `R` (
  `SID` smallint(6) unsigned NOT NULL,
  `RID` smallint(6) unsigned NOT NULL,
  `VID` varchar(50) NOT NULL DEFAULT '',
  `Col_1_to_3` smallint(1) DEFAULT NULL,
  `T` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`SID`,`RID`,`VID`),
  KEY `L` (`SID`,`VID`,`Col_1_to_3`),
  CONSTRAINT `R_f1` FOREIGN KEY (`SID`) REFERENCES `S` (`SID`),
  CONSTRAINT `R_f2` FOREIGN KEY (`SID`, `VID`) REFERENCES `V` (`SID`, `VID`),
  CONSTRAINT `R_f3` FOREIGN KEY (`SID`, `VID`, `Col_1_to_3`) REFERENCES `L` (`SID`, `VID`, `LID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

问题答案:

取决于您要查询的内容和查询的内容。

通常,对于EXPLAIN中每个具有的行Using where,您都需要使用索引(possible keyskeys列)来使它。这些是您的过滤器,包括WHERE和ON。说得Using index更好。这意味着有一个覆盖索引,MySQL可以直接从索引中检索数据,而不必访问表数据中的行。

Using where应该查看没有的行,它返回大量行。这些是表中所有行的返回值。我不知道您的查询是什么,所以我不知道是否在这里被提醒。尝试过滤结果集以减小大小并提高性能。

通常,您应该尽量避免看到Using filesortUsing temporary,尽管只有在不期望它们的情况下它们才是不好的。

Filesort通常与ORDER子句一起出现。通常,您希望MySQL使用覆盖索引(Using index),以便已按顺序从服务器返回行。如果不是,则MySQL必须在以后使用文件排序对其进行排序。

Using temporary当它引用派生表时可能会很糟糕,因为它们没有索引。看来您已经用索引明确创建了一个临时表,所以在这里还不错。有时,您唯一的选择是使用派生表,因此Using temporary



 类似资料:
  • 本文向大家介绍MySql中如何使用 explain 查询 SQL 的执行计划,包括了MySql中如何使用 explain 查询 SQL 的执行计划的使用技巧和注意事项,需要的朋友参考一下 explain命令是查看查询优化器如何决定执行查询的主要方法。 这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的。 1、什么是MySQL执行计划

  • 问题内容: MySQL Explain plan中的含义是什么? 注意:为便于阅读,已编辑输出。 问题答案: 这意味着您执行的查询只不过计算表中的行数而已,该表是MyISAM表。MyISAM表是用单独的行数存储的,因此,执行此查询MySQL根本不需要查看任何表行数据。而是立即返回预先计算的行数。因此,对表的访问被“优化了”,查询速度很快。 在MySQL中的其他存储引擎(例如InnoDB)上不会发生

  • 主要内容:1 调用EXPLAIN,2 EXPLAIN中的列,2.1 id,2.2 select_type,2.3 table,2.4 type,2.5 possible_keys,2.6 key,2.7 key_len,2.8 ref,2.9 rows,2.10 Extra详细介绍了MySQL EXPLAIN执行计划的各个字段的含义以及使用方式。 调用EXPLAIN可以获取关于查询执行计划的信息,以及如何解释输出。EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法,但该动能也有局限性,

  • 本文向大家介绍MySQL查询语句过程和EXPLAIN语句基本概念及其优化,包括了MySQL查询语句过程和EXPLAIN语句基本概念及其优化的使用技巧和注意事项,需要的朋友参考一下 网站或服务的性能关键点很大程度在于数据库的设计(假设你选择了合适的语言开发框架)以及如何查询数据上。 我们知道MySQL的性能优化方法,一般有建立索引、规避复杂联合查询、设置冗余字段、建立中间表、查询缓存等,也知道用EX

  • 本文向大家介绍MySQL性能优化神器Explain的基本使用分析,包括了MySQL性能优化神器Explain的基本使用分析的使用技巧和注意事项,需要的朋友参考一下 简介 MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化. EXPLAIN 命令用法十分简单, 在 SELECT 语句前加上 Expla

  • 本文向大家介绍Mysql深入探索之Explain执行计划详析,包括了Mysql深入探索之Explain执行计划详析的使用技巧和注意事项,需要的朋友参考一下 前言 如何写出效率高的SQL语句,提到这必然离不开Explain执行计划的分析,至于什么是执行计划,如何写出高效率的SQL,本篇文章将会一一介绍。 执行计划 执行计划是数据库根据 SQL 语句和相关表的统计信息作出的一个查询方案,这个方案是由查