🌱 起因:我写的第一个学生管理系统
最近在学习 C# WinForms,做了一个简单的“学生信息管理系统”,功能就是增删改查。数据库用的是 SQL Server,表结构如下:
CREATE TABLE Students (Id INT IDENTITY(1,1) PRIMARY KEY,Name NVARCHAR(50) NOT NULL,Age INT,Email NVARCHAR(100)
);
一开始,我查询数据时图省事,直接写了:
string sql = "SELECT * FROM Students";
dataGridView1.DataSource = SQLHelper.Query(sql);
程序跑得挺快,数据也显示正常。心想:“SELECT * 真方便,不用写字段名!”
⚠️ 转折:老师说“别用 SELECT *”
后来在看教程时,发现很多老师都强调:
“不要在生产代码中使用
SELECT *!”
我一开始不理解:明明能用,为什么不让用?难道只是“代码规范”?
直到我做了个小实验……
🔍 实验:SELECT * 和 SELECT Id, Name... 有啥区别?
我往 Students 表里插入了 1 万条测试数据(用脚本生成),然后分别测试两种写法:
✅ 写法1:明确指定字段
string sql = "SELECT Id, Name, Age, Email FROM Students";
❌ 写法2:偷懒用 SELECT *
string sql = "SELECT * FROM Students";
📊 结果对比(本地 SQL Server Express)
| 指标 | SELECT * |
明确字段 |
|---|---|---|
| 查询耗时 | ~850 ms | ~220 ms |
| 内存占用(WinForms) | 高(DataGridView 卡顿) | 低(流畅) |
| 网络传输量 | 大 | 小 |
💡 虽然只有 4 个字段,但
SELECT *仍然慢了近 4 倍!
🤔 为什么 SELECT * 会变慢?
通过查资料,我总结了几个原因:
1. 传了“不需要的数据”
- 我的 DataGridView 只显示
Name和Age,但SELECT *把Id和Email也传过来了。 - 多余的数据 = 多余的网络传输 + 多余的内存占用。
2. 数据库没法“走捷径”
- SQL Server 可以为常用查询建“索引”(就像书的目录)。
- 如果你只查
Name和Age,数据库可以建一个“覆盖索引”,直接返回结果,不用翻整张表。 - 但
SELECT *要所有字段,索引帮不上忙,只能老老实实查整行 → 变慢。
3. 未来可能“埋雷”
- 假如以后表里加了一个
Photo VARBINARY(MAX)字段(存照片)。 - 那么
SELECT *会把每张照片都传过来!程序直接卡死。 - 而明确写字段的代码完全不受影响。
✅ 正确做法:明确列出你需要的字段
现在我的代码都改成这样了:
// 只查 DataGridView 需要的字段
string sql = "SELECT Id, Name, Age, Email FROM Students ORDER BY Id";
dataGridView1.DataSource = SQLHelper.Query(sql);
虽然多打几个字,但换来的是:
- 更快的速度
- 更低的资源占用
- 更强的可维护性
🧭 给初学者的建议
- 开发阶段可以用
SELECT *快速调试,但正式代码一定要写明字段。 - 只查你需要的字段,不要“贪多”。
- 养成好习惯:写 SQL 前先想清楚“我到底要什么数据?”
- 如果表字段很多,可以在 SQL Server Management Studio (SSMS) 里右键表 → “脚本表作为” → “SELECT 到” → “新查询编辑器窗口”,自动生成字段列表。
有时候人只需要一只温暖的手的触摸,就像是拥有了整个世界。我一直在等,等到绝望