当前位置: 首页 > news >正文

基于 FastAPI + Vue 深度定制的全栈自动化执行引擎设计全解

MySQL 中的 count 三兄弟:效率大比拼!

一、快速结论(先看结论再看分析)

方式 作用 效率 一句话总结

count(*) 统计所有行数 最高 我是专业的!我为统计而生

count(1) 统计所有行数 同样高效 我是 count(*) 的马甲兄弟

count(列名) 统计该列非 NULL 的行数 ? 较慢 我挑剔,我只数非空值

结论:用 count(*) 就对了! ?

二、代码示例:亲测三兄弟的差别

准备测试数据

-- 创建测试表

CREATE TABLE user_test (

id INT PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(50),

age INT,

email VARCHAR(100)

);

-- 插入测试数据(故意插入一些NULL值)

INSERT INTO user_test (name, age, email) VALUES

('张三', 25, 'zhangsan@example.com'),

('李四', NULL, NULL),

('王五', 30, 'wangwu@example.com'),

(NULL, 28, 'unknown@example.com'),

('赵六', 35, NULL);

测试查询

-- 查看表中的数据

SELECT * FROM user_test;

/*

+----+--------+------+--------------------+

| id | name | age | email |

+----+--------+------+--------------------+

| 1 | 张三 | 25 | zhangsan@example...|

| 2 | 李四 | NULL | NULL |

| 3 | 王五 | 30 | wangwu@example.com |

| 4 | NULL | 28 | unknown@example.com|

| 5 | 赵六 | 35 | NULL |

+----+--------+------+--------------------+

*/

-- 测试1:count(*) 统计所有行数

SELECT count(*) FROM user_test; -- 结果:5 ?

-- 翻译:"老板,我有多少行数据?全都要!"

-- 测试2:count(1) 统计所有行数

SELECT count(1) FROM user_test; -- 结果:5 ?

-- 翻译:"老板,你给我个固定值1,我数有多少个1"

-- 测试3:count(列名) 统计非NULL的行数

SELECT count(name) FROM user_test; -- 结果:4 ?(NULL的那行没算)

SELECT count(age) FROM user_test; -- 结果:4 ?(NULL的那行没算)

SELECT count(email) FROM user_test; -- 结果:3 ?(两个NULL都没算)

-- 翻译:"我只数有身份证的人,黑户不算"

三、深入剖析:它们到底有啥不同?

1. 语义区别(最重要的区别!)

-- count(*) 是 SQL 标准写法

-- 意思:给我这个表有多少行数据

-- 相当于:"这个会议室有多少个座位?"

-- count(1) 是 count(*) 的一种写法

-- 意思:统计有多少个1

-- 相当于:"给每个座位发个苹果,最后数苹果"

-- count(列名) 是统计该列非NULL值的数量

-- 意思:这个会议室有多少人带了手机

-- 相当于:"检查每个座位,如果有人带了手机就计数"

2. 性能区别(神话与现实)

传说中的误解:

"count(1) 比 count(*) 快" ?

"count(主键) 最快" ?

现实真相:

MySQL 5.7 及以后版本:

count(*) 和 count(1) 性能完全相同

MySQL 优化器会把它们当作一回事

查看执行计划证明:

EXPLAIN SELECT count(*) FROM user_test;

EXPLAIN SELECT count(1) FROM user_test;

EXPLAIN SELECT count(id) FROM user_test;

-- 你会看到:前两个的执行计划完全一样!

性能排序(一般情况):

count(*) ≈ count(1) ?

count(主键列)

count(非主键有索引列) ?

count(非主键无索引列)

为什么 count(列名) 可能更慢?

-- 假设 email 列有索引

SELECT count(email) FROM user_test;

/*

MySQL 需要:

1. 读取索引(如果该列有索引)

2. 检查每个值是否为 NULL

3. 只计数非 NULL 的

如果 email 列没有索引:

1. 读取整行数据(比 count(*) 读的更多)

2. 检查 email 是否为 NULL

3. 只计数非 NULL 的

*/

3. 特殊情况分析

-- 情况1:所有列都不允许NULL

CREATE TABLE user_not_null (

id INT PRIMARY KEY NOT NULL,

name VARCHAR(50) NOT NULL

);

-- 这时候:count(*) = count(id) = count(name)

-- 情况2:空表 vs NULL值

CREATE TABLE empty_table (id INT);

SELECT count(*) FROM empty_table; -- 结果:0

SELECT count(id) FROM empty_table; -- 结果:0

INSERT INTO empty_table VALUES (NULL);

SELECT count(*) FROM empty_table; -- 结果:1

SELECT count(id) FROM empty_table; -- 结果:0 ?

四、实际工作中的选择指南

场景1:统计总行数

-- ? 正确做法

SELECT count(*) FROM orders;

-- ? 错误做法

SELECT count(order_id) FROM orders; -- 万一有NULL呢?

SELECT count(1) FROM orders; -- 能用,但不是标准

场景2:统计有效数据数量

-- 统计有多少用户填写了邮箱

SELECT count(email) FROM users; -- ? 这个场景就该用 count(列名)

-- 统计已完成订单数量(假设 status=2 是已完成)

SELECT count(*) FROM orders WHERE status = 2; -- ?

场景3:统计非重复值

-- 统计有多少个不同的城市

SELECT count(DISTINCT city) FROM users; -- ? count + DISTINCT

-- 统计有多少个城市,排除 NULL

SELECT count(DISTINCT city) FROM users; -- DISTINCT 会自动排除 NULL

五、性能优化技巧

1. 大表优化方案

-- 方案1:使用近似值(适用于统计概览)

SELECT TABLE_ROWS

FROM information_schema.TABLES

WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'big_table';

-- 方案2:分页总数缓存(适用于列表页)

-- 第一次查询时缓存总数,后面定时更新

-- 方案3:使用汇总表

CREATE TABLE stats_daily (

date DATE PRIMARY KEY,

user_count INT,

order_count INT

);

2. 索引优化

-- 为 count(列名) 创建索引

CREATE INDEX idx_email ON users(email);

-- 但注意:count(*) 不一定需要索引,InnoDB有优化

六、有趣比喻帮你记忆

汉堡店排队比喻

-- 有10个人在排队买汉堡

count(*) = "队列里有10个人" ?

count(1) = "我给每人发个号码牌,数有10个牌" ?

count(现金) = "只有8个人带了现金" ?

count(会员卡) = "只有5个人有会员卡" ?

教室点名比喻

-- 教室里有50个座位

count(*) = "教室有50个座位" ?

count(1) = "我在每个座位放本书,最后数有50本" ?

count(学生) = "今天来了45个学生上课" ?(空座位不算)

七、总结与最佳实践

最终建议

统计总行数,一律用 count(*)

这是 SQL 标准写法

性能最优(MySQL有专门优化)

语义最明确

统计某列非 NULL 数量,用 count(列名)

这是它的本职工作

不要用它统计总行数

关于 count(1)

性能与 count(*) 一样

但不够"标准",像方言

建议统一用 count(*)

性能关键点

大表避免频繁 count

考虑使用缓存或汇总表

为 count(列名) 的列加索引

一张图看懂

count(*) -> 总数 -> 最快 -> 推荐使用

count(1) -> 总数 -> 一样快 -> 可用但不标准

count(主键) -> 总数 -> 次快 -> 主键非NULL时可用

count(索引列) -> 非NULL数 -> 较慢 -> 有索引时可用

count(普通列) -> 非NULL数 -> 最慢 -> 谨慎使用

记住口诀:"数总数,用星号;数非空,列名好;数字1,虽高效,不是标准别当宝"骄星筒狡

http://www.jsqmd.com/news/643804/

相关文章:

  • PMO-N8N
  • 改进型Z源逆变器拓扑及其并网研究
  • 【信奥业余科普】04:承载“0和1”的物理躯壳——从30吨的庞然大物到指甲盖大小的微缩奇迹
  • AI智能二维码工坊技术解析:H级容错编码原理与实现
  • ZoteroDuplicatesMerger架构设计与性能优化:学术文献去重插件的技术实现深度解析
  • 南宁AI物业试点刷屏!广西/南宁/桂林物业系统推荐
  • 【原创】IgH EtherCAT主站详解(二十三)--DC 同步实战
  • 分享孙盈舞蹈场地设施、音乐搭配、成人舞蹈教学,性价比高不高 - 工业设备
  • GLM-TTS快速体验:开箱即用,免费生成高质量语音
  • 有实力的长安跨越V5二手车购买平台推荐,新能源二手车值得购买吗分析 - 工业推荐榜
  • 如何用 port.start 开启共享子线程与主页面的长连接通道
  • 从吐槽到规则:Karpathy 如何给 AI 编程立规矩
  • 033.API服务优化:异步处理、批处理、GPU内存管理
  • MTools企业应用:客服中心智能语音质检系统
  • a 进制转 b 进制(2~16)
  • AIVideo新手入门:手把手教你配置镜像,快速开启AI视频创作
  • SAP MM DIEN类型服务料号的采购
  • 3分钟解密网易云音乐NCM文件:ncmdump技术解析与应用指南
  • C++ 继承与派生入门:从基础到实践
  • 有实力的预制直埋保温管厂家探讨,生产工艺成熟度深度剖析 - mypinpai
  • ncmdumpGUI完全指南:5分钟掌握网易云音乐NCM文件转换技巧
  • 番茄小说下载器终极指南:一键将在线小说转为EPUB电子书
  • 3分钟快速上手:智慧树自动刷课插件的完整使用指南
  • 财务主管警示:企业云支出浪费比例或高达30%
  • NBTExplorer:Minecraft玩家的终极NBT编辑器完全指南
  • 八股(四)JVM
  • Window Resizer完整指南:免费工具解决Windows窗口无法调整的难题
  • 2026年带压封堵施工公司哪家性价比高,这些品牌值得考虑 - myqiye
  • 3个实用技巧:如何用ncmdump轻松解密网易云音乐NCM文件
  • 5个高级配置技巧:如何深度优化NVIDIA Profile Inspector