MySQL-为什么计数时使用“COUNT”;大于;“快,但是”;少于;需要永远吗?

MySQL-为什么计数时使用“COUNT”;大于;“快,但是”;少于;需要永远吗?,mysql,count,performance,comparison-operators,Mysql,Count,Performance,Comparison Operators,如果我运行该查询,需要一秒钟的时间,但如果我切换比较运算符,则需要几秒钟的时间。现在,第一种方法是计数=0,第二种方法是计数=120000,但是如果我只计算整个表,也需要几微秒 但是有一些奇怪的事情正在发生,因为如果查询真的完成了,它会在之后运行得非常快。MySQL正在缓存查询还是什么?嗯,我不想依靠缓存来确保网站不会挂起 这似乎是荒谬的:如果它能很快计算出超过某个日期的所有数据,那么为什么还要花更长的时间来计算相反的数据呢?不管是哪种方式,它都必须查看整张桌子,对吗?它需要返回的只是一个数字,

如果我运行该查询,需要一秒钟的时间,但如果我切换比较运算符,则需要几秒钟的时间。现在,第一种方法是计数=0,第二种方法是计数=120000,但是如果我只计算整个表,也需要几微秒

但是有一些奇怪的事情正在发生,因为如果查询真的完成了,它会在之后运行得非常快。MySQL正在缓存查询还是什么?嗯,我不想依靠缓存来确保网站不会挂起

这似乎是荒谬的:如果它能很快计算出超过某个日期的所有数据,那么为什么还要花更长的时间来计算相反的数据呢?不管是哪种方式,它都必须查看整张桌子,对吗?它需要返回的只是一个数字,所以带宽不应该是个问题

解释查询:

SELECT count(*) c FROM full_view WHERE verified > ( DATE (NOW()) - INTERVAL 30 DAY)

编辑:

这可能会引起一些兴趣,我在运行查询时发现了以下信息:

SELECT count(*) c FROM full_view WHERE verified > ( DATE (NOW()) - INTERVAL 30 DAY)
处理器\u读取\u rnd\u下一步:

  • 254436689(当执行的操作少于时)
  • 2(对于大于
按键读取请求: 314393对33(使用大于时,33是所有统计数据的最大数字)

处理程序\u读取\u键: 104303对1

绕过视图并直接在主表上运行查询可以消除这种缓慢。那么我需要做些什么来加速它呢?该视图基本上如下所示:

1, 'SIMPLE', 'b', 'range', 'updated,verified_index', 'updated', '3', '', 28, 'Using where'`    
1, 'SIMPLE', 'l', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'xyz_main.b.loc_id', 1, 'Using index'
1, 'SIMPLE', 'f', 'ALL', '', '', '', '', 2214, ''

已解决: 弗兰基把我的计划引向正确的方向。第二个联接表(company表)通过公司的全文名称联接。我最近才决定向该表添加一个整数键。“名称”列本应编入索引,但我可能弄糟了。不管怎样,我重新组织了一切。我将主表中的外键转换为与公司表的整数ID匹配,而不是与公司全名匹配。我重新索引了每个表中的这些列,然后更新视图以反映新的连接点。现在,它可以立即在两个方向上运行。:)所以我猜整数键是关键。问题已经解决了,但我觉得我原来的问题并没有真正解决


谢谢你们的帮助。

我猜从
日期(Now())
中减法需要很长时间来处理。对于已经小于
Date(Now())
verified
值,计算可能会短路,因为在该点上它必须为false(在比较“大于”时)

在与“小于”进行比较的情况下,无论当前值如何,在任何情况下都必须减去日期时间,因为在计算日期时间减法之前,无法从逻辑上推断表达式为真或假


不过,这只是一个猜测-请恕我直言。

如果您在表中的
上有一个已验证的
索引,则限制性更强的
计数(即>一个)会更快。不带WHERE子句的COUNT(*)可以快速返回,因为可以从表/索引统计信息中收集计数。

可能存在这样的情况,即有统计信息告诉数据库引擎,30天前没有已验证的记录。在这种情况下,它甚至不需要读取表格,而是从统计直方图中获取信息。

请运行下面的查询并发布结果

SELECT x, y, z, verified FROM table1 LEFT JOIN table2 on tab2_ID = table2.ID LEFT JOIN table3 on tab3_ID = table3.ID
被遗忘已久的人几乎总是会带来一些东西


编辑1:
这可能是进攻路线:

EXPLAIN SELECT count(*) c 
FROM full_view 
WHERE verified > ( DATE (NOW()) - INTERVAL 30 DAY)
ALL
there表示有一个完整的表格扫描

你可以深入研究这个问题

一定要试着看看差异在哪里


编辑2:


编辑3:
解释命令的逐步分析

1, 'SIMPLE', 'f', 'ALL', '', '', '', '', 2214, ''

我假设
full_view
是一个视图,它的定义是什么?解释计划告诉你什么?full_view包含主表(带有验证列)与其他两个表左键连接。主表是people,另外两个表连接location和company info。这很直截了当。你能试着在视线之外做吗?只是为了让我们看看有什么变化?我要去睡觉了。明天我会检查的。@Moss,我们可以得到一堆数据来处理这些值吗?使用一个明确的日期也会花费很长时间。@Moss,很有趣,也许我的想法是不正确的。把比较的顺序颠倒一下怎么样?与其做
A
,不如做
B>A
,看看是否需要同样长的时间——它应该执行完全相同的(我猜)有趣的想法,但现在尝试已经太迟了。我用betters键/索引解决了这个问题。将比较放在计数中是更好的语法,但它不会加快速度。我确实在
验证
上有一个索引。事实上,这种方法在两个方向上都很慢。