SQL中写in、not in带来的隐患
【背景】一个查询"未下单用户"的接口,明明库里有两百多个符合条件的用户,返回结果却是空。没有报错,没有超时,就是干干净净一个空数组。排查了两个小时,最后定位到一行SQL:SELECT*FROMcustomerWHEREidNOTIN( SELECTcustomer_idFROMorders);问题出在哪?orders.customer_id里有一条 NULL。就这一条 NULL,把整个查询结果干没了。不是慢,不是报错,是逻辑上直接变成 false。两百多个用户,一个都没查出来。这种bug最阴的地方在于:SQL执行成功了,单元测试通过了,数据量小的时候一切正常。等数据量上来、NULL值混进去,它才突然发作,而且不声不响。一、IN 不是不能用,但要看场景先说IN。很多人一听SQL优化就开始背八股:"别用IN,要用EXISTS。"这话只对一半。小集合用IN完全没问题:SELECT*FROMordersWHEREstatusIN('PAID','SHIPPED','FINISHED');状态就三个值,数据库很好处理。你非要改成EXISTS,那是为了优化而优化,没意义。真正要警惕的是大子查询:SELECT*FROMcustomerWHEREidINn