一:Count(*) 的实现方式?

  - 要明确的是,在不同的 MySQL 引擎中,count(*) 有不同的实现方式。

  - MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高(前提是不加where条件)

  - 而 InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

二: 为什么 InnoDB 不跟 MyISAM 一样,也把数字存起来呢?

  - 因为即使是在同一个时刻的多个查询,由于多版本并发控制(MVCC)的原因,InnoDB 表“应该返回多少行”也是不确定的。

  - 也是和MVCC获取一致性视图的问题。具体要抓取哪个一致性视图作为标准。

  - 每一行记录都要判断自己是否对这个会话可见,因此对于 count(*) 请求来说,InnoDB 只好把数据一行一行地读出依次判断,可见的行才能够用于计算“基于这个查询”的表的总行数。

三:MyIsam 和 InnoDB 的总结。

  - MyISAM 表虽然 count(*) 很快,但是不支持事务;

  - show table status 命令虽然返回很快,但是不准确;(空洞问题)

  - InnoDB 表直接 count(*) 会遍历全表,虽然结果准确,但会导致性能问题。

四: Count ?

  - 概念

    - count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。最后返回累计值。

  - 区分(不同的count使用方式)

    count(主键 id) 

      - InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。

    - count(1)

      -  InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。

    - count(1) 执行得要比 count(主键 id) 快。因为从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。

    - count(字段)

      - 如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;

      - 如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加。

     但是 count(*) 是例外

      -  并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加。

    - 所以结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),建议尽量使用 count(*)。

 

五:解决 count 性能问题

  - 缓存记录条数 (注意缓存和数据库的一致性问题)

  - 数据库记录条数(类型汇总表,开启事务,保证一致性问题)

  - 使用 explain / show table status 等近似值(不准确)

《Mysql - Count(*) 的优化》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. PC 端常用软件

    WPS  金山文档  有道云笔记  格式工厂 运行精灵 UC 遨游 360 Firefox 浏览器 光影魔术手 美图秀秀 2345好压 火绒安全软件 有道云笔记 悟空游戏厅 微信 QQ 迅雷 百度网盘 ...

  2. ciscn2019华北赛区半决赛day2_web1题解

    比赛结束以后采用非官方复现平台做的题,和比赛题有轻微不同,比赛中存放flag的table是ctf,这里是flag. 题目地址 buuoj.cn 解题过程 题目中只有一个页面,需要提交id. id为1, ...

  3. H5注意点(1)

    H1标签在企业开发中,每一个页面至多只能有一个H1标签,被H1标签包裹的是整个页面最重要的信息. img标签,格式:<img src=" ">,当中src就是用来告诉i ...

  4. Language Modeling with Gated Convolutional Networks(句子建模之门控CNN)--模型简介篇

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/liuchonge/article/deta ...

  5. postgresQL 服务器端守护进程

  6. intel 性能分析

    分析memory bound,etc https://software.intel.com/en-us/articles/intel-vtune-amplifier-tutorials

  7. Python3基础 只有int类型,没有long类型

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  8. TeslaManage 2.0编译日志

    1>------ 已启动全部重新生成: 项目: TeslaManage, 配置: Debug x64 ------1> Moc'ing teslamanage.h...1> Uic' ...

  9. 全面系统Python3入门+进阶-1-1 导学

    python特点 结束

  10. VS编译出错不自动运行上次的程序