所以我想说我正在构建这个联系人管理系统。有一个USER表和一个CONTACT_INFO表。 对于每个USER,我可以有零个或多个CONTACT_INFO记录。我定义它的方式,我在CONTACT_INFO表中设置了一个外键,指向相关的USER记录。
我想搜索没有CONTACT_INFO记录的所有USER记录。
我希望可以这样做:
SELECT * FROM user u WHERE u.user_id NOT IN (SELECT DISTINCT c.user_id FROM CONTACT_INFO);
我担心的是,随着表的增长,此查询的性能会显着下降。
我正在玩的一个想法是在USER表中添加一个列,说明它是否有任何CONTACT_INFO记录。另外,我想知道,如果在CONTACT_INFO中插入任何记录,DBMS必须验证记录是否存在,为了验证而已经访问该记录并因此更新它,当我更新CONTACT_INFO记录时不应该这是代价高昂的,性能方面的。
一如既往,感谢您的反馈。
答案 0 :(得分:3)
最简单的方法是:
SELECT (...)
FROM user u
LEFT OUTER JOIN CONTACT_INFO c
ON u.user_id = c.user_id
WHERE c.user_id IS NULL
它看起来更笨重,但应该更好地扩展。
答案 1 :(得分:2)
从我的测试中,以下内容比BradC的方法更快:
select (...)
from user u
where not exists (select null from CONTACT_INFO c where u.user_id = c.user_id)
这可能是因为编译器本身不得不进行转换,我不知道。
但是,Le Dorfier原则上是正确的:如果您已经在数据库上设置了索引(即两个user_id列都应该被编入索引),那么您的答案和大多数这些响应将非常快,无论如何您在数据库中拥有的许多记录。顺便提一下,如果您正在寻找一种方法来获取列出用户的查询以及“HasContactInfo”布尔值,您可以执行以下操作:
select u.(...),
(case when exists (select null from CONTACT_INFO c where c.user_id = u.user_id) then 1
else null
end) has_contact_info
from user u
这个第二个解决方案在您的情况下可能没有用,但我发现它比一些我认为会自动优化的更简单的查询要快得多。
答案 2 :(得分:1)
你有理由认为性能会降低吗?这是SQL中最有效的查询类型之一。但放弃DISTINCT。
答案 3 :(得分:1)
至少在oracle中,我使用
获得了更好的性能其中0 =(从CONTACT_INFO c中选择计数(*),其中......)
而不是NOT IN子句。