SQL最佳实践:不要再比较 count(*) = 0
SQL best practices – don’t compare count(*) with 0
每次看到这样的SQL都会让我抓狂:
SELECT u.* FROM users u
WHERE 0 = (SELECT COUNT(*) FROM addresses a WHERE a.user_id = u.id);
一起来分析一下这样写有什么问题,如何避免这种写法。
写这样的SQL,明显是为了搜索出没有填写地址的用户列表。
这么写不对吗?我们是找没有地址的用户,看起来也没有什么问题,问题在于计数!!!
如果有个用户关联了上百万的地址,系统就要全查出来,并统计出数量!!!
实际上哪怕没有上百万的地址记录,如果有2个、3个,这种计数的性能损耗也是非常多余的。
所以,什么样的SQL才适用于这种情况呢?答案就是 EXISTS
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT FROM addresses a WHERE a.user_id = u.id);
EXISTS (示例中是 NOT EXISTS) 会高效率检查是否至少有一条地址纪录,而不用计数。
当然,总有人说我这么写也没有错吧啦吧啦,是的,所以标题是最佳实践,建议大家养成好的SQL或编程习惯,只有这样才能避免极端情况下的错误。
引用
转自 depesz@depesz.com 的blog,近期刚好用到,特此记录。