Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解如何设计MySQL索引以获得良好的性能_Mysql - Fatal编程技术网

了解如何设计MySQL索引以获得良好的性能

了解如何设计MySQL索引以获得良好的性能,mysql,Mysql,通过反复试验,我为这个查询找到了一个很好的索引,但我真的很想了解为什么这个索引和只有这个索引有帮助,以及如何避免下次重复测试和评估 日志表的InnoDB表结构为: 这是我的查询,它查找日志中有一种操作但没有另一种操作的所有用户。它还限制了特定的组织值和特定的日期范围 SELECT DISTINCT USER AS 'Dormant Users' FROM db.log WHERE `action` = @a1 AND `org` = @orgid AND `logdate` >=

通过反复试验,我为这个查询找到了一个很好的索引,但我真的很想了解为什么这个索引和只有这个索引有帮助,以及如何避免下次重复测试和评估

日志表的InnoDB表结构为:

这是我的查询,它查找日志中有一种操作但没有另一种操作的所有用户。它还限制了特定的组织值和特定的日期范围

SELECT DISTINCT USER AS 'Dormant Users'
FROM db.log
WHERE `action` = @a1
  AND `org` = @orgid
  AND `logdate` >= @startdate
  AND USER NOT IN (SELECT DISTINCT USER
             FROM db.log
            WHERE `action` = @a2
              AND `org` = @orgid
              AND `logdate` >= @startdate)
;
如果没有索引,这大约需要21秒,解释说明如下:

所以,我认为在org、logdate和action上建立索引可能会有所帮助。如果我按照精确的顺序在这些列上创建索引,查询时间将减少到大约0.3秒,解释输出现在是:

但是,如果我在索引中更改列的顺序,甚至只是在用户列上添加另一个不相关的索引,查询大约需要2秒钟


因此,我如何理解甚至设计索引,使其在该查询的基础上运行良好,并避免添加另一个索引而损害性能的情况?或者这只是一个测试的例子,看看什么是有效的?

我的答案不是答案,因为它不是关于如何设置索引,而是关于如何编写查询以提高效率

如果子查询不是小表,请避免使用NOT IN:

选择DISTINCT l1.USER作为“休眠用户” 从db.log l1 其中`action`=@a1 和'org`=@orgid 和'logdate`>=@startdate 不存在,请选择1 从db.log l2 其中l1.`user`=l2.`user` l1.`org`=l2.`org` 和l2.`action`=@a2 l2.`logdate`>=@startdate ;
编辑:我删除了解释链接,因为它不是我所想的。我只是一个熟练的开发人员,而不是DBA。因此,我优化了很多查询,并且当卷达到hihg时,使用NOT EXISTS(不存在)的结果总是比使用NOT IN(不存在)的结果更好。但我无法就内部原因进行辩论,我想这取决于RDBMS,我的答案不是答案,因为这不是关于如何设置索引,而是如何编写查询以提高效率

如果子查询不是小表,请避免使用NOT IN:

选择DISTINCT l1.USER作为“休眠用户” 从db.log l1 其中`action`=@a1 和'org`=@orgid 和'logdate`>=@startdate 不存在,请选择1 从db.log l2 其中l1.`user`=l2.`user` l1.`org`=l2.`org` 和l2.`action`=@a2 l2.`logdate`>=@startdate ;
编辑:我删除了解释链接,因为它不是我所想的。我只是一个熟练的开发人员,而不是DBA。因此,我优化了很多查询,并且当卷达到hihg时,使用NOT EXISTS(不存在)的结果总是比使用NOT IN(不存在)的结果更好。但我无法对内部原因进行争论,我想这取决于RDBMS或外部连接

SELECT DISTINCT user 
           FROM log x
           LEFT
           JOIN log y
             ON y.user = x.user
            AND y.org = x.org
            AND y.action = @a2
            AND y.logdate > = @startdate
          WHERE x.action` = @a1
            AND x.org = @orgid
            AND x.logdate >= @startdate
            AND y.user IS NULL;

我对索引不是很感兴趣,但我会从org、action、logdate开始,或者从外部连接开始

SELECT DISTINCT user 
           FROM log x
           LEFT
           JOIN log y
             ON y.user = x.user
            AND y.org = x.org
            AND y.action = @a2
            AND y.logdate > = @startdate
          WHERE x.action` = @a1
            AND x.org = @orgid
            AND x.logdate >= @startdate
            AND y.user IS NULL;

我对索引不是很感兴趣,但我会从org、action、logdate开始,我们能否拒绝这个问题的前提,因为另一个查询可能会更快?你应该专注于编写一个好的查询,而不是索引一个坏的查询。这是一个可怕的问题。如果您希望查询速度更快,请不要使用子查询,也不要使用NOT IN。这可能更适合DBA。我们是否可以因为另一个查询可能更快而拒绝问题的前提?您应该专注于编写一个好的查询,而不是索引一个坏的查询。这是一个可怕的问题。如果希望查询快速进行,请不要使用子查询,也不要使用NOT IN。这可能更适合DBA。您可以参考NOT IN而不是NOT IN的缺点吗?请记住,NOT IN是邪恶的:。你可以从这篇文章中看到它是邪恶的还是效率低下?@OlivierDepriester实际上,该主题中引用的文章的摘要说明了相反的情况。@OlivierDepriester请看上面我的评论和Gnudiff。你能澄清一下你的答案吗?其中提到的一篇文章与你所写的内容相矛盾?由于这是迄今为止的最佳答案,人们可能会感到困惑。我还使用分析器对3种主要方法进行了一些测试,得到了一些非常奇怪的结果,比如分析器说查询耗时1.7秒,但挂钟显示为20秒。因此,我将按照Gnudiff所说的做,并尝试使用DBA堆栈。您能指出不存在而不是不存在的缺点吗?请记住,不存在是邪恶的:。你可以从这篇文章中看到它是邪恶的还是效率低下?@OlivierDepriester实际上,该主题中引用的文章的摘要说明了相反的情况。@OlivierDepriester请看上面我的评论和Gnudiff。你能澄清一下你的答案吗?其中提到的一篇文章与你所写的内容相矛盾? 由于这是迄今为止的最佳答案,人们可能会感到困惑。我还使用分析器对3种主要方法进行了一些测试,得到了一些非常奇怪的结果,比如分析器说查询耗时1.7秒,但挂钟显示为20秒。所以我将按照Gnudiff所说的做,并尝试使用DBA堆栈。