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

2024-02-10

查看查询的EXPLAIN计划中,如何确定哪些地方可以进行最佳优化?

我很欣赏首先要检查的事情之一是是否使用了好的索引,但除此之外我有点困惑。通过过去的尝试和错误,我有时发现执行连接的顺序可以是一个很好的改进来源,但是如何通过查看执行计划来确定这一点呢?

虽然我非常希望对如何优化查询有一个良好的总体了解(建议阅读,非常感谢!),但我也意识到讨论具体案例通常比抽象讨论更容易。由于我目前正在用这个把头撞在墙上,因此非常感谢您的想法:



id   select_type   table   type     possible_keys    key       key_len   ref                    rows   Extra
 1   SIMPLE        S       const    PRIMARY,l,p,f4   PRIMARY         2   const                     1   Using temporary
 1   SIMPLE        Q       ref      PRIMARY,S        S               2   const                   204   Using index
 1   SIMPLE        V       ref      PRIMARY,n,Q      Q               5   const,db.Q.QID            6   Using where; Using index; Distinct
 1   SIMPLE        R1      ref      PRIMARY,L        L             154   const,db.V.VID          447   Using index; Distinct
 1   SIMPLE        W       eq_ref   PRIMARY,w        PRIMARY         5   const,db.R.RID,const      1   Using where; Distinct
 1   SIMPLE        R2      eq_ref   PRIMARY,L        PRIMARY       156   const,db.W.RID,const      1   Using where; Distinct
  

我对执行计划最后一行的解释是否正确:

  • 因为它在主键上完全匹配,所以只有一行R2需要按输出行获取;
  • 但是,此类输出行随后会根据适用于的某些条件进行过滤R2?

如果是这样,我的问题在于最后一步中发生的过滤。如果条件导致不进行过滤(例如WHERE `Col_1_to_3` IN (1,2,3)),查询运行速度极快(~50ms);但是,如果条件限制所选行(WHERE `Col_1_to_3` IN (1,2)),查询需要相当长的时间(~5s)。如果限制是单个匹配 (WHERE `Col_1_to_3` IN (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 is:

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 keys and keys柱子)。这些是您的过滤器,包括 WHERE 和 ON。话虽这么说Using index甚至更好。这意味着存在覆盖索引,MySQL 可以直接从索引检索数据,而不是访问表数据中的行。

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

您通常应该尽量避免看到Using filesort or Using temporary,尽管只有在你没有预料到的情况下这些才是糟糕的。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何基于EXPLAIN计划优化MySQL查询 的相关文章

  • Hibernate 乐观锁..它是如何工作的?

    我正在阅读下面关于休眠乐观锁定的博客 我打算将它与休眠一起使用 但是 我有一个担忧 我们有java代码和c 代码 都连接到一个数据库 虽然java代码可以使用hibernate来实现乐观锁定 但我想让c 代码做同样的事情 此外 C 代码正在
  • MySQL - 返回每个 GROUP BY 的 X 个数字

    在此查询中 我指定要返回的汽车型号 硬编码 所以下面的 SQL 返回one每个模型的记录 SELECT FROM main WHERE marka name SUBARU AND model name IMPREZA AND kuzov G
  • 连接多个表的查询执行速度慢

    我有以下表格 Parts id int idx partnumber varchar idx accountnumber idx enabled Sample data RefUserGroup id int idx value varch
  • 如何调试 MySQL 存储过程?

    我当前的调试存储过程的过程非常简单 我创建一个名为 debug 的表 在存储过程运行时从其中插入变量值 这允许我查看脚本中给定点的任何变量的值 但是有没有更好的方法来调试 MySQL 存储过程 下列debug msg可以调用过程来简单地将调
  • 在 Toad for MySQL 中执行 SELECT 语句时出现错误

    当我尝试执行一个简单的 SELECT 语句时 出现此错误Toad MySql Data Types MySqlConversionException Unable to convert MySQL date time value to Sy
  • 如何在通过 Laravel Eloquent 方法连接的元素上使用 orderby

    问题是查询无法找到应该与 Laravel Eloquent 中的方法WITH 连接的特定方法 特定方法 特定模型 特定模型 特定方法等 有什么想法如何解决吗 我的代码 SpecificModel
  • HTAccess - 令人困惑的干净网址

    如果我想简单地重定向 clients page to clients php view page我会使用像这样简单的东西 它效果很好 Options FollowSymlinks RewriteEngine on RewriteRule c
  • Mysql - Mysql2::错误:字符串值不正确:

    所以我建造了一个刮刀并拉动一些物体 问题是有些是外语 它使 mysql 数据库有点崩溃 这是我得到的错误 知道我能用这个做什么吗 谢谢 Mysql2 错误 列的字符串值不正确 xC5 x8Dga 第 1 行的 描述 插入sammiches
  • Java 从 SQL 数组获取 ResultSet 失败

    我试图从数据库中检索电子邮件地址 但没有成功 我的代码如下 Main System out println PortfolioData getEmails 58 So Far Returning null 投资组合数据 public sta
  • 使用mysql在一个查询中选择多个表中的子项总数

    我整个下午都在尝试处理一个查询 或两个或三个 以获得三个表的所有子表的计数 看看我的设计 用户表 id user name 1 foo 2 bar 赢表 id won user 1 1 2 1 3 2 绘制表格 id draw user 1
  • MySQL SELECT 输出同一行中每个 id 的下一个日期

    我查询的表结构如下 ID Date Before value After value 1 2014 04 25 Win Loss 1 2014 04 30 Loss Win 1 2014 08 18 Win Loss 1 2014 08 2
  • Codeigniter 加入多个条件

    我正在使用 Codeigniter Active Records 课程 我想加入我的users与我的桌子clients表 这样我就可以显示用户的 真实 姓名 而不仅仅是他们的 ID 这是什么clients表看起来像 示例 列 a 1 a 2
  • MySQL InnoDB 查询性能

    我正在尝试优化一个简单的 sql 查询 该查询将多次运行大量数据 这是场景 MySQL 与 InnoDB 表 where 和 join 中使用的所有字段都已索引 表有 FK 我不需要查询的整个缓存 但每个表的缓存是可能的 表有更多的更新 插
  • MySQL 服务器未启动

    当我做 mysql u root p并输入my password这就是我得到的 错误 2002 HY000 无法通过套接字 var run mysqld mysqld sock 连接到本地 MySQL 服务器 2 所以我输入 systemc
  • 如何在 phpmyadmin 中创建 MySQL 触发器

    我想在 MySQL 中创建一个触发器 我运行以下命令 mysql gt delimiter mysql gt CREATE TRIGGER before insert money BEFORE INSERT ON money gt FOR
  • Mysql innoDB 不断崩溃[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的数据库 mysql 服务器不断崩溃 重新启动 我不知道该怎么办 我不断在 dbname org err 文件中收到以下内容 13120
  • 为什么 MySQL 创建带有 _seq 后缀的表?

    我创建了一个 InnoDB 表 名为foo在 MySQL 中 一旦我对表执行插入操作 我就会看到另一个表foo seq被建造 如果我删除自动生成的表 它会在下一次插入后出现 是什么原因造成的 听起来像是正在创建一个序列 您是否有自动生成的主
  • 无法启动 MySQL 服务器 - 控制进程退出并出现错误代码

    我的 mysql 服务器停止后无法启动 命令使用 sudo etc init d mysql restart Error 重新启动 mysql 通过 systemctl mysql serviceJob for mysql service
  • Python:如何使用生成器来避免 sql 内存问题

    我有以下方法来访问 mysql 数据库 并且查询在服务器中执行 我无权更改有关增加内存的任何内容 我对生成器很陌生 并开始阅读更多有关它的内容 并认为我可以将其转换为使用生成器 def getUNames self globalUserQu
  • 如何在 Laravel 查询中使用多个 OR,AND 条件

    我需要 Laravel 查询帮助 我的自定义查询 返回正确结果 Select FROM events WHERE status 0 AND type public or type private 如何写这个查询Laravel Event w

随机推荐

  • 捕获承诺中的拒绝

    我想保留错误func reject 不直接到onError 通过选择 在我总是让func resolve 并确定后的返回结果yield func 如果我想直接前往onError use throw 想知道有什么更好的主意我可以让func r
  • RedirectToAction 到另一个控制器中的操作不起作用

    在我的 mvc3 POST ActionResult 方法中 我有一部分如下代码 if button Save as Pdf RedirectToAction getPdf Pdf resultObtained 当用户单击按钮时 它会将用户
  • Python配置文件:有什么文件格式推荐吗? INI格式还合适吗?看起来很老派

    我需要存储 Python 应用程序的配置 键 值 并且我正在寻找将这些配置存储在文件中的最佳方法 我遇到了Python的配置解析器 http docs python org library configparser html我想知道 INI
  • 使用 rspec 调用特定 url

    我想在 rspec 中创建一个 get 请求 get exec query gt bla id gt something user id gt user 这会构建一个类似以下的 URL user query something exec q
  • 在静默模式下安装 sqlcmd 接受 EULA

    我正在尝试以静默模式安装 sqlcmd 但我不知道如何自动接受 EULA 我尝试安装的文件名为 MsSqlCmdLnUtils msi 从 MS 下载中心下载 这是我到目前为止所尝试过的 通过谷歌找到 msiexec i MsSqlCmdL
  • 隐藏部分溢出的元素

    我正在寻找一种纯 CSS 方法来隐藏已部分溢出其容器的 div 3 请参阅附图 这是一个可行的解决方案 它将完全隐藏不适合其父级固定高度的项目 Codepen https codepen io PhilippeVay pen JyBQOy
  • 用模型方法查询?

    我在仅对活动对象执行查询时遇到问题 我在数据库中没有活动列 相反 在模型游戏上 我有以下方法 def complete self winner true false end 这样如果一场比赛有赢家 complete 将返回 true 我想查
  • 微服务异步操作HTTP响应

    我们正在构建一个微服务应用程序 客户可以在其中创建projects 下图展示了该过程的技术流程 我的问题 API 网关应向客户端返回什么 HTTP 响应 步骤 1 我最初的想法是返回 202 但问题是我不知道Location yet pro
  • SQL - 两个相互依赖的外键

    目前的结构如下 Table RowType RowTypeID Table RowSubType RowSubTypeID FK RowTypeID Table ColumnDef FK RowTypeID FK RowSubTypeID
  • 使用 otool(递归)查找应用程序所需的共享库

    我有一个 Cocoa 应用程序 它使用 otool 来查找应用程序正常运行所需的共享库 例如 假设我在使用 QTKit framework 的应用程序上运行 otool L 我得到了程序使用的共享库的列表 包括 Cocoa framewor
  • 无法加载文件或程序集“Microsoft.Web.Deployment,版本=9.0.0.0”

    我有 VS 2013 Ultimate 我的远程服务器是 IIS 7 5 并启用了远程部署 我已通过 Web Platform Installer 4 6 安装了 Web Deploy Tool 2 1 并且安装成功 当我尝试在发布工具上验
  • 如何告诉 DBD::mysql mysql.sock 在哪里?

    将 DBD mysql 与 DBI 一起使用 尝试连接到数据库时出现以下错误 DBI connect database mydb host localhost someuser failed Can t connect to local M
  • pyqtSlot 的功能[重复]

    这个问题在这里已经有答案了 我刚刚阅读了有关 pyqt5 按钮的教程here https pythonspot com en pyqt5 buttons 代码如下 有一个问题是关于button clicked connect self on
  • Grails - 跨控制器代码,在每个请求上执行

    有没有办法在调用任何控制器操作之前执行某些代码 我需要根据获取参数的值设置会话变量 而不考虑调用哪个控制器 当然 一旦完成此处理 请求需要按照其正常方式到达相应的控制器 操作 Thanks 听起来你想使用filter http grails
  • 树的等级是多少? (如树ADT)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 据我所知 一个节点的度数是它拥有的子节点的数量 但是 我们如何定义树的度呢 基本上 树的度是它的子节点的总数 即源自它的节点的总数 树的叶
  • HTTP 响应何时完成?

    我正在 NET 中编写一个简单的 HTTP 客户端用于学习目的 我正在使用 NETSocket http msdn microsoft com en us library system net sockets socket aspx类 最终
  • 在工厂模式中使用反射[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在工厂模式中使用反射是一个好的实践吗 public class MyObjectFactory private Party party publ
  • 获取iscsi设备的目标IP地址

    假设我有一个 iSCSI 设备 dev sdat 我如何知道其目标的IP地址 目标驱动程序是 SCST 启动程序是 iSCSI 我只知道一个名为 dev sdat仅此而已 那么如何获取目标的IP地址呢 嗯 我并不为此感到自豪 但它完成了工作
  • 如何利用模板复制&移动构造函数和赋值运算符?

    考虑以下 C 代码以及我试图避免的失败尝试非模板复制和移动构造函数和赋值运算符的偏好 https stackoverflow com a 32539424 1915854 template
  • 如何基于EXPLAIN计划优化MySQL查询

    查看查询的EXPLAIN计划中 如何确定哪些地方可以进行最佳优化 我很欣赏首先要检查的事情之一是是否使用了好的索引 但除此之外我有点困惑 通过过去的尝试和错误 我有时发现执行连接的顺序可以是一个很好的改进来源 但是如何通过查看执行计划来确定