热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

count(*)实现原理

count(*)实现原理不同引擎的实现:MyISAM引擎把表的总行数存在了磁盘上,执行COUNT(*)就会直接返回,效率很高;InnoDB在count(*)时,需要把数据一行一行的


count(*)实现原理



  • 不同引擎的实现:



    • MyISAM引擎把表的总行数存在了磁盘上,执行COUNT(*)就会直接返回,效率很高;

    • InnoDB在count(*)时,需要把数据一行一行的从引擎里面取出来然后累计记数。

    • 注意如果有where过滤条件MYISAM速度就不是很快了。



  • 为什么Innodb不和MYISAM一样?



    • 根本原因:即使在同一时刻的多个查询,由于MVCC的原因,Innodb对于应该返回多少行也是不确定的,比如以下场景例子(设计了三个用户并行会话):



      • 会话A先启动事物并查询一次表的总行数;

      • 会话B启动事物,插入一行记录后,查询表的总行数

      • 会话C启动一个单独语句,插入一行记录后,查询表的总行数。



    • 假设从上到下是按时间顺序执行的,同一行语句,在同一时刻执行,拿到的数据却是不一样的。





      • 解决方法:





        • 虽然会话B的读操作仍然是在T3执行的,但是因为这时候更新事务还没有提交,所以计数值加1这个操作对会话B还不可见。









  • count(*),count(主键),count(1),count(字段)区别



    • count(id) :Innodb会遍历整张表,把每一行的id都取出来,返回给server,server层拿到id后,判断是不可能为空的,按行累加。

    • count(1):innodb遍历整张表,但不取值,server层对于返回的每一行,放一个数字1进去,判断是不肯能为空的,按行累加。

    • count(字段):

      • 如果这个字段定义为not null的话,一行行从记录里读出这个字段,判断不能为null,按行累加

      • 如果允许为null的话,执行的时候,判断到有可能是null,还要把值取出来判断以下,不是null才累加。



    • count():并不会把全部字段取出来,而是专门做了优化,不取值。count(*)肯定不

      是null,按行累加。

    所以结论是:按照效率排序的话,count(字段)



两阶段提交MYSQL异常重启会出现什么现象





  • 如果在图中时刻A的地方,也就是写入redo log 处于prepare阶段之后、写binlog之前,发生了崩

    溃(crash),由于此时binlog还没写,redo log也还没提交,所以崩溃恢复的时候,这个事务会

    回滚。这时候,binlog还没写,所以也不会传到备库。



  • 主要集中在时刻B,也就是binlog写完,redo log还没commit前发生 crash,那崩溃恢复的时候MySQL会怎么处理?



    • 崩溃恢复时的判断规则

      1. 如果redo log里面十五是完整的,也就是已经有了commit表示,则直接提交

      2. 如果redo log里面的十五只有完整的prepare,则判断对应事物的binlog是否完整,是则提交,否则回滚



    • 所以在B时刻崩溃食物会被提交。



  • MySQL是怎么知道binlog完整的?



    • 一个事务的binlog是有完整格式的:statement格式的binlog,最后会有COMMIT;row格式的binlog,最后会有一个XID event。



  • redo log和binlog是怎么关联起来的



    • 它们有一个共同的数据字段,叫XID。崩溃恢复的时候,会按顺序扫描redo log:

    • 如果碰到既有prepare、又有commit的redo log,就直接提交;

    • 如果碰到只有parepare、而没有commit的redo log,就拿着XID去binlog找对应的事务。



  • 为甚么要两阶段提交



    • 对于InnoDB引擎来说,如果redo log提交完成了,事务就不能回滚(如果这还允许回滚,就可能 覆盖掉别的事务的更新)。而如果redo log直接提交,然后binlog写入的时候失败,InnoDB又回 滚不了,数据和binlog日志又不一致了。

      两阶段提交就是为了给所有人一个机会,当每个人都说“我ok”的时候,再一起提交。





  • 正常运行中的实例,数据写入后的最终落盘,是从redo log更新过来的还是从 buffffer pool更新过来的呢?



    • redo log并没有记录数据页的完整数据,所以它并没有能力自己去更新磁盘数据页,也就不存在“数据最终落盘,是由redo log更新过去”的情况。

      1. 如果是正常运行的实例的话,数据页被修改以后,跟磁盘的数据页不一致,称为脏页。最终 数据落盘,就是把内存中的数据页写盘。这个过程,甚至与redo log毫无关系。

      2. 在崩溃恢复场景中,InnoDB如果判断到一个数据页可能在崩溃恢复的时候丢失了更新,就会将它读到内存,然后让redo log更新内存内容。更新完成后,内存页变成脏页,就回到了第 一种情况的状态。







推荐阅读
  • 本文总结了多种MySQL监控工具和日志分析工具,包括innotop的安装与使用介绍、mysqlsniffer及其工作原理,以及tcpdump的应用。同时,还介绍了mysqldumpslow和maatkit等日志分析工具,旨在帮助数据库管理员有效监控和优化MySQL性能。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中安装MySQL 5.5.37时遇到的启动失败和PID文件问题,并提供了详细的解决方案,包括日志分析、权限检查等步骤。 ... [详细]
  • sqlserver动态分区方案例子
    sqlserver动态分区方案例子当我们存储的数据量比较大时,比如超过千万,上亿级别时单纯的使用索引可能效果不明显了,此时我们可以考虑采 ... [详细]
  • 本文探讨了如何在TWiki中配置自定义标记,以实现特定字符串(如#12345)自动转换为指向票务系统的超链接。此功能类似于在其他平台上的实现,旨在提高信息检索效率。 ... [详细]
  • VMware Horizon View 5.0桌面虚拟化部署实践与心得
    在近期的研究中,我花费了大约两天时间成功部署了桌面虚拟化环境,并在此过程中积累了一些宝贵的经验。本文将分享这些经验和部署细节,希望能对同样关注桌面虚拟化的同行有所帮助。 ... [详细]
  • 使用ASP.NET与jQuery实现TextBox内容复制到剪贴板
    本文将介绍如何利用ASP.NET结合jQuery插件,实现将多行文本框(TextBox)中的内容复制到用户的本地剪贴板上。该方法主要适用于Internet Explorer浏览器。 ... [详细]
  • 本文详细介绍了在 Ubuntu 16.04 系统中使用 APT-GET 包管理器安装 MySQL 5.7 数据库的过程,并对安装后的文件和目录结构进行了说明,包括重要的配置文件及其功能。 ... [详细]
  • Node.js 入门指南(一)
    本文介绍了Node.js的安装步骤、如何创建第一个应用程序、NPM的基本使用以及处理回调函数的方法。通过实际操作示例,帮助初学者快速掌握Node.js的基础知识。 ... [详细]
  • window下kafka的安装以及测试
    目录一、安装JDK(需要安装依赖javaJDK)二、安装Kafka三、测试参考在Windows系统上安装消息队列kafka一、安装JDKÿ ... [详细]
  • 本文详细介绍了使用ZooKeeper构建高可用集群的方法,包括必要的软件环境准备、配置文件调整及集群启动等关键步骤。通常,一个ZooKeeper集群由奇数个节点组成,以确保Leader选举的有效性。 ... [详细]
  • 在服务器虚拟化领域,用户面临多种选择,尤其是来自同一供应商的不同产品。正确评估这些选项对于项目的成功至关重要。本文将深入探讨VMware提供的两款主要虚拟化平台——免费的VMware Server和付费的ESX Server之间的区别,旨在为决策提供专业指导。 ... [详细]
  • 本文介绍了如何通过扩展 Panel 控件来实现滚动条位置的自动保存和恢复。类似于 Page 的 MaintainScrollPositionOnPostBack 属性,我们将在自定义的 TBPanel 控件中添加相同的功能。 ... [详细]
  • 本文档详细介绍了在 Kubernetes 集群中部署 ETCD 数据库的过程,包括实验环境的准备、ETCD 证书的生成及配置、以及集群的启动与健康检查等关键步骤。 ... [详细]
  • 热璞数据库与云宏达成兼容性互认证,共筑数据安全屏障
    热璞数据库与云宏信息技术有限公司近期宣布完成产品兼容性互认证,旨在提升数据安全性与稳定性,支持企业数字化转型。 ... [详细]
  • Spring Boot 入门指南
    本文介绍了Spring Boot的基本概念及其在现代Java应用程序开发中的作用。Spring Boot旨在简化Spring应用的初始设置和开发过程,通过自动配置和约定优于配置的原则,帮助开发者快速构建基于Spring框架的应用。 ... [详细]
author-avatar
Mr_cool
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有