Mysql 性能和计数(*)

Posted

技术标签:

【中文标题】Mysql 性能和计数(*)【英文标题】:Mysql performance and Count(*) 【发布时间】:2009-10-06 14:02:56 【问题描述】:

我想知道我的 sql 在线性时间或 log(n) 时间内执行计数查询,我认为如果查询参数被索引,它可以通过 cubing 来完成

【问题讨论】:

【参考方案1】: MyISAM 将立即返回。 InnoDB 会进行 PK 扫描,因此时间会随着记录数的增加而线性增加。

如果您需要查看 InnoDB 表大约保存了多少条记录,最快的方法是使用

EXPLAIN select * from student;

(但innodb的统计数据可能有误,所以40%的错误也很有可能)

【讨论】:

这适用于普通的“SELECT COUNT(*) FROM myTable”查询。然而,时间复杂度各不相同,查询包含任何过滤器或其他约束。 40% 错误?怎么可能错得这么远?这是一个真正的问题,我不是 mysql 用户所以我不知道。 对于 InnoDB 来说,预测要扫描的行数有 40% 的错误是非常可能的。但是97%的执行计划是准确的。 (好吧,当需要索引提示时,可能会伤害其他 3%)【参考方案2】:

这完全取决于查询,或者更准确地说,取决于 MySql 最终选择来处理查询的查询计划。

在这些大 O 表达式中,这完全取决于我们所说的“n”是什么意思。例如,如果“n”是最终返回的计数值,并且如果该计数是由需要迭代扫描多个表的查询产生的,则复杂性可能比线性更差。

【讨论】:

【参考方案3】:

这个问题的答案很复杂。它不仅取决于所涉及的表的数量,还取决于您使用的存储引擎。

话虽如此,手册上是这样说的:

COUNT(*) 被优化为返回非常 如果 SELECT 从 一张表,没有其他列 检索到,并且没有 WHERE 条款。例如:

mysql> SELECT COUNT(*) FROM student;

此优化仅适用于 仅限 MyISAM 表,因为精确 存储此存储的行数 引擎,可以非常访问 迅速地。用于事务存储 InnoDB 等引擎,存储一个 确切的行数更成问题 因为可能有多个交易 发生,每一个都可能影响 计数。

-- MySQL Manual

【讨论】:

我的查询包含 where 子句,但 where 子句中的属性已编入索引。我可以使用例如立方体或相同的技术吗?

以上是关于Mysql 性能和计数(*)的主要内容,如果未能解决你的问题,请参考以下文章

Mysql 计数给了我一个非常糟糕的性能,我做错了吗?

MySQL进阶实战6,缓存表视图计数器表

性能计数器是实现和平均每秒计数的最佳方法吗?

使用trace分析mysql性能问题

使用trace分析mysql性能问题

MySQL进阶实战6,缓存表视图计数器表