Rad*_*zea 21 mysql innodb count
每个人都知道,在使用 InnoDB 作为引擎的表中,诸如此类SELECT COUNT(*) FROM mytable的查询非常不准确且非常慢,尤其是当表变大并且在该查询执行时不断插入/删除行时。
据我了解,InnoDB 不会将行数存储在内部变量中,这就是导致此问题的原因。
我的问题是:为什么会这样?存储这样的信息有那么难吗?在许多情况下,这是一个重要的信息。我看到是否要实现这样的内部计数的唯一困难是当涉及事务时:如果事务未提交,您是否计算它插入的行数?
PS:我不是数据库方面的专家,我只是一个将 MySQL 作为一个简单爱好的人。因此,如果我只是问一些愚蠢的问题,请不要过分挑剔:D。
Rem*_*anu 16
对于初学者来说,没有诸如“当前计数”之类的东西要存储在变量中。类似查询SELECT COUNT(*) FROM ...受当前隔离级别和所有并发挂起事务的约束。根据隔离级别,查询可以看到或看不到由挂起的未提交事务插入或删除的行。唯一的答案是计算当前事务可见的行数。
请注意,我什至没有触及在计数期间开始或结束的并发事务的更棘手的主题。更不用说回滚了...
我同意@RemusRusanu(他的回答+1)
SELECT COUNT(*) FROM mydb.mytableInnoDB 中的行为就像事务存储引擎应该的那样。将其与 MyISAM 进行比较。
如果mydb.mytable是 MyISAM 表,启动SELECT COUNT(*) FROM mydb.mytable;就像运行SELECT table_rows FROM information_schema.table WHERE table_schema = 'mydb' AND table_name = 'mytable';. 这会触发对 MyISAM 表头中行数的快速查找。
如果mydb.mytable是 InnoDB 表,你会得到一大堆正在发生的事情。你有 MVCC 正在进行,管理以下内容:
向 InnoDB 询问表计数需要通过这些不祥的事情进行导航。事实上,人们永远不会真正知道SELECT COUNT(*) from mydb.mytable是只计算可重复读取还是包括已提交的读取和未提交的读取。
您可以尝试通过启用innodb_stats_on_metadata 来稍微稳定一下。
根据innodb_stats_on_meta_data上的 MySQL 文档
启用此变量时(这是默认值,与创建变量之前一样),InnoDB 在元数据语句(例如 SHOW TABLE STATUS 或 SHOW INDEX)期间或访问 INFORMATION_SCHEMA 表 TABLES 或 STATISTICS 时更新统计信息。(这些更新类似于 ANALYZE TABLE 发生的情况。)禁用时,InnoDB 在这些操作期间不会更新统计信息。禁用此变量可以提高具有大量表或索引的模式的访问速度。它还可以提高涉及 InnoDB 表的查询的执行计划的稳定性。
在设置 EXPLAIN 计划方面,禁用它可能会也可能不会为您提供更稳定的计数。它可能SELECT COUNT(*) from mydb.mytable以好的方式、坏的方式或根本不影响性能。试试看!
| 归档时间: |
|
| 查看次数: |
8181 次 |
| 最近记录: |