SQL查询。存在和连接之间的区别

时间:2016-01-19 15:18:48

标签: sql postgresql select join exists

我有4张桌子:

create table Product(pCode integer primary key, pName varchar(20), Color varchar(10);
create table Cli(cCode integer primary key, cName varchar(20), city varchar(20));
create table Sale(pOut integer references Product(tCode), cOut integer references Client(cCode), countOut integer, dtOut date, primary key (pOut, kOut);
create table Buy (pIn integer references Product(pCode), cIn integer references Client(cCode), countIn integer, dtIn date, primary key (pIn, kIn);

我需要显示客户的名字不是来自喀山,而是那些在2015年上半年购买一些商品,然后在2015年下半年销售相同商品的客户。

我通过使用视图解决了这个问题。

create view vA as select cCode from Cli where Cli.City <> 'Kazan';
create view vB(cCode, pCode) as select cOut, pOut from Sale where '01.01.2015'<=dtOut AND dtOut<'01.07.2015';
create view vC(cCode, tCode) as select cIn, tIn where '01.07.2015<=dtIn AND dtIn < '01.01.2016';
create view vD as select * from vB inner join vC on vB.cKod=vC.cKod AND vc.pCode=vB.pCode;
create view vE as select * from vD  right outer join on vA on vA.cCode=vD.cCode;
create view vF as select distinct c.Knam from Cli as c inner join vE on vE.cCode=c.cCode;

如果我要使用加入存在/不存在会不会有所作为?

例如对于vD - 存在而不是内连接:

create view vD as select * from vB where exists(select * from vC where B.cCode=vC.cCode AND vc.pCode=vB.pCode);

对于vE - 不存在而不是右外连接:

create view vE as select * from vA where not exists(select * from vD where vA.cCode=vD.cCode);

2 个答案:

答案 0 :(得分:0)

我认为存在是一种更好的解决方案,因为常识告诉我它应该更快。如果你说&#34;存在&#34;这意味着查询将在找到匹配时停止,但是当您说&#34;不存在时#34;它需要通过所有元素来确保它不存在。

另外,我想鼓励您使用更好的命名,因为查询现在很难阅读。

答案 1 :(得分:0)

这是使用EXPLAIN

最佳解答的问题之一

我的猜测是,您发现优化程序在INNER JOINWHERE EXISTS之间选择相同的方法(相反,Right Outer Join / Is Null vs {{1因为它们在这种情况下大致相同,而且Postgres有一个很好的优化器。

Here's a good example某人正在为您的Not Exists查询执行完全相同的测试,他的结果是Postgres为这两种方法选择了vE

最后,如果您不确定哪条路线是最佳路线,那么只需写下两条路线,看看效果最好的路线。查询运行后检查统计信息并查看Hash Anti Join