2019-08-17第十四讲:count(*)这么慢[mysql实战45讲]

需求: 需频繁统计总记录数.

1. count(*)实现方式

    1.MyISAM ==> 总行数 写盘 ==> 很快

    2.InnoDB ==> 从引擎中一行行读数据, 累计 ==> 很慢

    注意: 有where则MyIASM没那么快

    3. 为什么Innodb 不存起来?  ==> 支持事务 , MVCC  ==> 可见的行才能从引擎中取出来.

    4. count(*) 还是做了优化的 ==> 哪个索引树小 ,就扫描哪个

 数据库系统设计法则: 保证逻辑正确前提下, 尽量减少扫描的数据量. 

    5.show table status  ==> 是根据索引统计采样估算的, 误差40% -50% 


2.用缓存系统保存计数.

    1.使用redis ==> 可能会丢失更新 ==> 解决方案: 如果redis异常重启, 则查一遍count(*), 再放进缓存中

    2.使用redis ==> 逻辑上不精确


1.插入数据, 再加1
2. redis加1  再插入

3.在数据库保存计数 ==> 推荐使用

            1.解决崩溃丢失问题

            2.解决并发问题

4.不同的count用法

    1.count()

        what: 是一个聚合函数 ,对于返回结果集一行行的判断, 不是null就累计加1.

    2.原则: 

        1.server层要什么就给什么

        2.Innodb 只给必要的值

        3.优化器优化了count(*)的语义为"取行数"

        

    3.count(主键) :  遍历表,  取每行id, 返回server,  server判断不可能为空, 累加

        count(1) :  遍历表, 不取值, server每行放一个1,  server判断不可能为空, 累加

        count(字段): 遍历表,  取每行字段, 返回server,  server判断是否为空, 累加

        count(*): 遍历表, 不取值, 按行累加 ==> 专门优化过

    4.结论: 效率排序:    * > 1 > 主键 > 字段. 

注意: 两个不同的存储系统, 不支持分布式事务, 无法拿到精确一致的视图

你可能感兴趣的:(2019-08-17第十四讲:count(*)这么慢[mysql实战45讲])