14count函数
count(*) 的实现方式
count语义:聚合函数,一行行判断结果集,如果count函数的参数不是NULL加1;
count(主键id),InnoDB遍历整张表,把每行id取出返回server层server层拿到id,判断不可能为空,按行累加
count(1) InnoDB遍历整张表,不取值。server层对返回的每行,放数字“1”进去,判断是不可能为空,按行累加。
count(*) 做了专门优化,不取值,按行累加。优先采用二级索引(数据量少执行效率效率高)
MyISAM 引擎记录总行数直接返回,加where条件需额外处理
InnoDB 把数据一行一行地从引擎里面读出来,然后累积计数。因为MVCC的原因不同隔离级别返回行数不确定。
mysql优化器找最小索引树遍历,普通索引叶节点只存储主键,索引数据量相对小,遍历哪个索引数结果都相同。
结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(),所
以我建议你,尽量使用 count()。
缓存行数的问题
redis缓存,存在一致性问题
如下:
时刻 | 回话A | 回话B |
---|---|---|
T1 | ||
T2 | Redis +1 | |
T3 | 读Redis计数;查询最近100条记录 | |
T4 | 插入一行数据R | |
T5 |
在数据库保存计数
数据库本身解决奔溃丢失问题
InnoDB支持事务,可以解决一致性问题
时刻 | 回话A | 回话B |
---|---|---|
T1 | ||
T2 | begin;表C计数+1 | |
T3 | begin;读取表C计数;查询近100条记录;commit | |
T4 | 插入一行数据R;commit |