3.4 查询性能排错手记


3.4 查询性能排错手记

本节摘要:查询变慢的原因九成集中在四类:缺索引、条件里包函数、嵌套失控、数据搬运方式不当。本节给出一个五步诊断流程和一份病灶对照表,并复盘华彩项目一次真实的"月结查询卡死"排查全程。

系统上线两个月后的一个周五傍晚,华彩的财务打来电话:"月结对账查询点了之后一直转圈,十分钟都出不来。"这是每个 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 没有执行计划面板。 服务器数据库的开发者习惯"看计划定优化",这里没有这个福气,只能靠受控实测替代:同一查询改动前后各跑三遍取平均,秒表计时落进变更日志。土办法的好处是无处不在——任何版本都能用,而且数字直接进文档,说服客户比任何理论都快。

其二:优化要有预算线,别无限内卷。 我们给自己定的验收口径叫"两秒守则":高频操作页签上的任何查询,首屏结果两秒内出现即视为合格;年 度盘点类低频查询放宽到十秒。守住这条线后就停手去干别的活——性能工作是围绕业务节奏的服务,不是炫技的深坑。华彩那次优化到四秒其实已经达标,我们继续做的第四刀纯粹因为夜间空闲资源不用白不用。

给新手的防复发清单

  • 新查询上线前先拿最坏数据量试跑一遍(年底数据复制一份当测试床);
  • 函数包裹字段、多层嵌套、无索引联接,三个雷区写入团队自查清单;
  • 每季度挑一个最慢页面重演一次五步流程,防止增量改动悄悄欠账。

插曲:一次被表象带偏的诊断

给排错五步法配一个反面插曲,提醒你别迷信流程的机械执行。华彩月结变慢初期,最先被怀疑的是报表端新增的条件格式——毕竟时间吻合、删掉后好像也快了几秒。我们沿着这个假设折腾了两天加缓存测试,直到老老实实跑计时对比才发现:条件格式的开销不到半秒,真正的病根在它下游一个三天前改过的汇总查询。判断一误,功夫全废。

教训沉淀为一条补充纪律:任何归因之前先做隔离测试——把嫌疑对象从链路上干净地摘掉再看计时,"摘掉后依然慢"才能洗清嫌疑。排查工程最贵的成本从来不是测量本身,而是在错误假设上堆起来的确认偏误。

防复发三件套接着送给你。

本节排错心法

  • 量化复现先行,区分环境病与查询病。
  • 五步流程可背:读结构、验联接、抓函数、试拆分、二分定位。
  • 四大修复术按性价比排序:补索引、解函数、剪嵌套、汇总前置。
  • "有名有姓的冗余"是性能优化的正当武器,但要写进字典注明刷新时点。

至此查询章节齐活。数据的答案有了,下一章解决"怎么把答案递到不懂技术的人手上"。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U