• MySQL的`count(expr)`函数选择指南


    MySQL的count(expr)函数选择指南

    1. 背景知识
    • 文章基于MySQL 8.0.30,使用InnoDB和MyISAM引擎。
    • count(expr): MySQL聚合函数,用于统计列值或表行数。
    • 统计列值: 只计非NULL值。
    • 统计表行数: 不区分NULL与否。
    2. 存储引擎差异
    • MyISAM: 表定义、数据、索引分别存储,行数存储于磁盘。
    • InnoDB: 所有内容存储于单一文件,无预先存储的行数。
    3. count(*)行为
    • MyISAM: 直接从磁盘读取行数,无where条件时高效。
    • InnoDB: 无预先存储行数,需逐行累加。
    4. MVCC与事务隔离级别
    • InnoDB支持事务,使用MVCC实现可重复读,影响count(*)行为。
    5. 性能分析
    • InnoDB优化:选择最小索引树遍历,减少数据量,提升性能。
    6. count(expr)函数详解
    • count(主键): 遍历表,返回主键值,统计总数。
    • count(1): 遍历表,Server层每行放置数字1,统计总数。
    • count(非主键字段): 统计字段值不为NULL的总数,可能少于实际行数。
    7. 源码分析
    • 实现: C++,item_sum.cc文件。
    • count(*): 内部视为count(0)
    • count(1): 直接处理为longlong类型1。
    • count(字段名): 处理为字段类型Item_field
    8. 总结
    • 效率排序: count(非主键字段) < count(主键) < count(1) ≈ count(*)
    • 推荐: 使用count(*),优化器选择最小索引树。
    • count(*): 包含NULL值的行数。
    • count(非主键字段): 不含NULL值的行数。
    9. show table status的准确性
    • 误差率: 40% ~ 50%,不推荐用于精确统计。
    10. 特殊情况
    • InnoDB单索引: count(*)count(1)通过主键索引统计。
    • InnoDB多索引: 优化器选择最小索引树。
    参考文献
    • MySQL-server GitHub源码
    • MySQL 8.0官方文档
    • MySQL 8.0 MyISAM引擎官方文档
    • MySQL 8.0 聚合函数官方文档

    建议

    • 优先使用count(*),利用MySQL优化器。
    • 考虑NULL值情况,选择合适的count(expr)变体。
    • 避免使用show table status获取精确行数。
  • 相关阅读:
    C++常用23种设计模式总结(三)------装饰模式
    leetcode-1.两数之和(哈希表解决)
    Error response from daemon: Get https://registry-1.docker.io/v2/
    算法基础:单链表图解及模板总结
    整理之前的书籍
    Linux之基于Centos系统安装Redis、MySQL、Nginx
    ChatGPT研究论文提示词集合3-【数据收集】、【数据分析】和【解释与讨论】
    电商运营管理——广告系统
    3. 常用服务器工具安装
    JS-函数
  • 原文地址:https://blog.csdn.net/modelsetget/article/details/140038624