sql测试
sql测试
上周三下午,我盯着屏幕上那条跑了十七分钟还没结束的SQL查询,咖啡杯沿已经凉透了。旁边同事老周凑过来看了一眼,啧了一声:“你这`LEFT JOIN`套了四层,索引全被绕晕了。”他随手把`WHERE`里的函数改写成范围条件,查询时间从十七分钟掉到三秒。那一刻我意识到,SQL测试测的不是语法,是人对数据分布的直觉。
很多人以为SQL测试就是跑通几个`SELECT`,比对一下结果集。真这么简单就好了。上个月我们上线一个报表功能,开发自测时一切正常,数据量才两万行。结果生产环境一跑,两千万行直接卡死,数据库CPU飙到百分之百,差点把核心交易系统拖垮。后来复盘发现,问题出在`IN`子查询里藏了个全表扫描——测试环境数据量小,优化器随便选个执行计划都能秒回,根本暴露不了问题。
所以我现在做SQL测试,第一件事是看执行计划。别急着看结果对不对,先问数据库打算怎么干这活。`EXPLAIN`一开,全表扫描、索引失效、临时文件排序,全现原形。有次测试一个分页查询,`ORDER BY`的字段没进索引,数据量一大就触发文件排序,内存不够直接落盘,慢得离谱。加了个覆盖索引,问题立刻消失。这种问题,光比对结果集永远发现不了。
还有一类坑更隐蔽——数据分布不均。比如订单表里有个`status`字段,百分之九十九的行都是“已完成”,剩下百分之一是“待支付”。你按`status`建索引,优化器可能根本不走,因为它觉得全表扫更快。测试时你得故意构造极端数据,把“待支付”的行数放大到十万级,看看查询计划会不会变。我吃过这亏,线上有个统计接口,平时毫秒级响应,某天突然飙到五秒,查了半天,原来是某商家批量导入了大量异常状态订单,直接击穿了优化器的判断。
写SQL测试用例也别太“干净”。真实数据里什么脏东西都有:NULL值、超长字符串、重复记录、甚至编码混乱的乱码。我习惯在每个测试表里塞几条“垃圾数据”,专门测边界情况。有次测一个字符串拼接逻辑,线上数据里混了个`NULL`,结果整列结果全变NULL,测试环境里根本没这情况,因为造数的人太规矩了。
最后说句实在话,SQL测试最该测的是“慢”而不是“错”。错误的结果一眼就能看出来,慢查询却像慢性病,等发现时往往已经拖垮了业务。我现在的习惯是,每写一条查询,都随手跑一下`EXPLAIN ANALYZE`,盯着实际执行时间发会儿呆。要是超过两百毫秒,就琢磨琢磨能不能改写。这习惯救过我好几回,最险的一次是某个后台导出功能,原本要跑三分钟,改写后变成八秒,产品经理还以为我偷偷加了缓存。
SQL测试的本质,是在跟数据库优化器博弈。你得懂它的脾气,知道它什么时候犯懒,什么时候犯傻。工具再多,不如自己对数据多一分敬畏。
本文地址:http://www.79wt.cn/news/079e0299918.html
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。