本节摘要:查询变慢的原因九成集中在四类:缺索引、条件里包函数、嵌套失控、数据搬运方式不当。本节给出一个五步诊断流程和一份病灶对照表,并复盘华彩项目一次真实的"月结查询卡死"排查全程。
系统上线两个月后的一个周五傍晚,华彩的财务打来电话:"月结对账查询点了之后一直转圈,十分钟都出不来。"这是每个 Access 维护者迟早接到的电话。这一节就把那次排错完整拆给你看,方法比个案重要。
排错第一步是把"慢"量化。让财务口述没用,我们约定两个度量:首次出结果的时间(按下去到第一屏数据显示)和全量完成时间(状态栏走完)。复测发现首次约四十秒、全量超过五分钟——已经从"体验差"升级为"影响下班",值得动手术。
其次要排除环境因素再怀疑自己写的代码。同一个文件在被杀毒软件实时扫描的共享目录上打开,人人都慢;拷到本机立刻变快,那是部署问题不是查询问题(这类环境病第 7 章专门处理)。本次测得本机运行同样慢,确认病灶在库内。
五步都有明确的检查动作,展开说:
第一步读结构。 把月结查询切到 SQL 视图通读,重点数 COUNT:几个联接、几层子查询、有没有查询套查询套查询的项链结构。这个案例里我们发现它引用了一个中间查询,而那个中间查询又引用了另一个——链深三层,每层都在重复扫描订单明细。
第二步验联接。 逐一核对每根联接线两端的字段类型(自动编号对长整型)和索引情况。华彩的问题第一个就出在这里:订单明细表的货品 ID 是后补的字段,建的时候忘了加索引,二十多万行每次联接都是全表互扫。
第三步抓函数。 条件行里凡是长这样的都要警惕——Format(下单日期,"yyyy-mm") = "2026-07"。括号一包,引擎无法使用该列的索引,只能逐行调用函数算一遍再比较,行数一大就慢成灾。
修复一:给外键补索引。 打开订单明细设计视图,在货品 ID 字段的"已索引"属性选"有(有重复)"。改完同一查询当场快了一半以上——这是全书性价比最高的一次点击。
修复二:把函数条件改成范围条件。 那个月份筛选改写成闭区间:
-- 改写前 无法走索引 WHERE Format(下单日期, "yyyy-mm") = "2026-07" -- 改写后 索引可直接定位 WHERE 下单日期 >= #2026-07-01# AND 下单日期 < #2026-08-01#
范围写法绕开了函数,索引重新上岗。同样的思路适用于一切"加工后再比较"的条件:能移到等号右边的加工就别包在列名外面。
修复三:剪断项链式嵌套。 三层嵌套的中间层其实只为得到"各单据小计"。我们在明细层加索引后,直接用一层带 GROUP BY 的查询取代了两层接力。经验法则重申一遍:SQL 里子查询最多一层,再多就拆具名查询串联——串联不只是性能手段,还是可读性手段,每一环都能单独调试。
修复四:汇总落表换取夜间空闲。 对账页签里有几项历史累计(本年累计销售额之类),实时现算每次都从头扫全年流水。改为每天早上由生成表查询刷新一次快照,白天所有报表只读快照。误差容忍度是关键前提——老板娘确认晨间刷新足以满足口径后才敢这么干。这招就是 2.2 说的"有名有姓的冗余"的性能版。

| 症状 | 高概率病因 | 一分钟自查 |
|---|---|---|
| 只有一台机器慢 | 前端未本地化或网络盘抖动 | 拷到本机对比 |
| 所有查询都渐慢 | 库文件膨胀或损坏前兆 | 先压缩修复,看文件大小变化 |
| 单个查询慢 | 本节四大病灶 | 走五步流程 |
| 结果集巨大才慢 | 正常物理规律 | 分页、限制输出列、必要时归档 |
| 越用越慢但不稳定 | 锁竞争或多用户编辑冲突 | 第 7 章拆分部署排查 |
特别强调压缩修复这项周维护动作——Access 的删除并不立即释放空间,文件像只胖不瘦的海绵,定期挤压本身就是免费的性能保养。
其一:Access 没有执行计划面板。 服务器数据库的开发者习惯"看计划定优化",这里没有这个福气,只能靠受控实测替代:同一查询改动前后各跑三遍取平均,秒表计时落进变更日志。土办法的好处是无处不在——任何版本都能用,而且数字直接进文档,说服客户比任何理论都快。
其二:优化要有预算线,别无限内卷。 我们给自己定的验收口径叫"两秒守则":高频操作页签上的任何查询,首屏结果两秒内出现即视为合格;年 度盘点类低频查询放宽到十秒。守住这条线后就停手去干别的活——性能工作是围绕业务节奏的服务,不是炫技的深坑。华彩那次优化到四秒其实已经达标,我们继续做的第四刀纯粹因为夜间空闲资源不用白不用。
给排错五步法配一个反面插曲,提醒你别迷信流程的机械执行。华彩月结变慢初期,最先被怀疑的是报表端新增的条件格式——毕竟时间吻合、删掉后好像也快了几秒。我们沿着这个假设折腾了两天加缓存测试,直到老老实实跑计时对比才发现:条件格式的开销不到半秒,真正的病根在它下游一个三天前改过的汇总查询。判断一误,功夫全废。
教训沉淀为一条补充纪律:任何归因之前先做隔离测试——把嫌疑对象从链路上干净地摘掉再看计时,"摘掉后依然慢"才能洗清嫌疑。排查工程最贵的成本从来不是测量本身,而是在错误假设上堆起来的确认偏误。
防复发三件套接着送给你。
至此查询章节齐活。数据的答案有了,下一章解决"怎么把答案递到不懂技术的人手上"。