如何确定慢查询的原因

时间:2016-01-26 14:12:26

标签: mysql

我的查询大约需要7秒钟。我把它分成两个查询,提供与第一个相同的数据,大约需要0.01秒。我曾经认为我正确地索引了它,但是,可能没有。数据库目前的数据非常少。我正在使用MySQL 5.5.46。我正在使用PHP与PDO,但是,我不认为这是相关的,故意没有用PHP或PDO标记这个问题。

我不是在问为什么我的特定查询花了这么长时间或如何识别慢查询,但我要求通用步骤来确定查询速度慢的原因。我希望会使用EXPLAIN。你在EXPLAIN寻找什么?可以采取哪些其他步骤?

5 个答案:

答案 0 :(得分:2)

Spencer7593是一个非常好的开始,但你不会在那里得到完整的答案,或者在StackOverflow上。部分解释让我about 40 pages full

EXPLAIN很有用 - 但需要在理解表和索引的结构的情况下阅读 - 从您的描述中看,优化器似乎忽略了索引。您可以强制数据库use a particular index进行查询,但这是一个相当不整洁的解决方案(即使您知道今天是最好的解决方案,也可能不会在将来)。

如果你有一个非常好的索引并且DBMS没有使用它,那么最可能的原因是cardinality stats have not been updated - 但是当数据非常偏斜时也会发生(例如,如果你有10000个值) ' A'以及' B'然后索引将帮助您查找包含' B'但不包含' A')的记录

始终使用索引并不总能让您的查询更快 - 从单个文件顺序读取比在2个文件上随机读取要快得多。

另一个警告是MySQL不能很好地处理推送谓词。

谨防连接中的隐式(和显式)类型转换 - MySQL不能使用索引。 Mariadb支持虚拟列(可以编制索引)。因此,如果你

var app = angular.module('iframeApp', ['ngSanitize']);

app.controller('iframeCtrl', function ($scope) {

$scope.html = "<h1>Add Code to see preview here</h1>";
$scope.css = '';

window.updatehtml = function (snippet) {
    $scope.$applyAsync(function () {
        $scope.html = snippet;
    });
};
window.updatecss = function (snippet) {
    $scope.$applyAsync(function () {
        $scope.css = snippet;
    });
};

})

优化器可以使用tab_b.seconds_since_epoch上的索引,但不能使用tab_a.datetime上的索引。

对于某些引擎(以及命名锁),DBMS中的其他活动可以阻止查询 - 尽管这种情况通常表现在基于统计数据的DBMS性能分析中,并且不太可能是这里的原因。需要采取另一个步骤来追踪正在进行阻止的行为。

将查询分解为更小的部分并独立测试它们是一个很好的诊断工具(kudos!),但只有当你查看所有EXPLAIN计划时,你才能理解为什么你会在复合材料中出现异常行为。

答案 1 :(得分:0)

最重要的是,如果你有可能使用phpmyadmin,那么有一个很好的分析器。

在phpmyadmin中调用查询后,您可以选择使用“性能分析”(在编辑锚点之前)

它为您提供了一个很好的图表和工作表和时间表,所以我认为这将是有帮助的。

答案 2 :(得分:0)

这是非常通用的,但我会尝试提供一些指导

  • 如果您在某个字段上执行搜索,那么第一个是Index,您需要该字段的索引。
  • 现在,如果您对多个字段而不是多个索引执行索引,则可能需要使用复合索引。
    • 过滤子查询不使用索引,因此如果您尝试过滤a,请小心 子查询。
    • 同时使用WHERE上的函数不使用索引,例如SUBSTRINGUPPER CASELIKE
  • 使用不INNER JOIN的{​​{1}}会导致ON并快速乘以行数。

CROSS JOIN中,您尝试查找Query Execution Plan而不是FULL SEQ SCAN

答案 3 :(得分:0)

解释显示子查询,实际使用的索引,扫描的行数等。 见mysql manual on its output

然后有一个神奇的&#34;盯着它&#34;方法,通常会产生关于如何减少查询复杂性的想法:

  • 更少的查询更好
  • 索引优于全表扫描
  • 连接可以比子查询更好
  • 更少的连接更好(因为连接会增加扫描的行,有时会多次)
  • 更具选择性的索引优于选择性较低的索引,因此在索引后较少的行仍然可以扫描
  • 分组和排序是额外费用
  • having可能比where更贵(因为分组后工作)

等等

答案 4 :(得分:0)

优化查询运行时的步骤。您应该在每个步骤后检查查询的速度 - 如果您可以在特定步骤中对其进行任何更改。:

  1. 一般来看看你的查询,并尝试确认它只查询它应该查询的内容。查找未使用的字段,不必要的连接,不必要的外连接。考虑使用limit来限制返回的记录数。请记住,组装比需要更大的结果集还需要额外的时间来创建并发送给客户端。
  2. 现在,再次仔细查看您的查询,看看是否可以简化它。例如,您可以在选择列表中包含子查询,您可以尝试将其转换为派生表。另请查看您的where条件,并确认它们是否可以使用索引(表达式,如'%xxx%'。如果不能,请检查是否可以将它们更改为可以使用索引的sg。
  3. 如果您在任何受影响的表上有任何索引,则可以使用analyse table命令刷新它们,只是为了安全起见。检查现有索引的基数。 Mysql不太可能使用低基数的索引。如果基数远远超出您的想象(给定字段中唯一值的数量),那么您可能需要调整mysql如何对数据进行采样以计算基数。
  4. 运行说明并检查是否
    • 索引用于您期望的位置(可能的键,使用的键)
    • 避免加入类型ALL和文件排序
  5. 尝试将索引添加到查询中未使用它们的那些部分,或者如果您相信已经有索引,则使用索引提示(例如force index)使mysql使用您的索引。

    1. 如果查询仍然很慢,那么您可能需要调整服务器端变量,使用不同的表引擎,分区表,更改数据结构(非规范化),归档旧数据以减小大小等。
    2. 您可以为每个步骤编写长文章,如果没有,则可以。 5,关于每个项目。