Sql 左连接与多个SELECT语句

Sql 左连接与多个SELECT语句,sql,Sql,我正在处理其他人的PHP代码,并一次又一次地看到这种模式: (伪代码) 如果另一个表中没有相关行,那么代码需要进行分支,但是在单个SELECT语句中执行左连接是否可以做得更好?我是否错过了一些性能优势?可移植性问题?还是我只是吹毛求疵?我同意你的观点-一个SQL会更好将SQL DBMS视为ISAM文件系统,一次从一个表中进行选择,这是一种危险。在外部联接中使用单个SELECT可能更干净。另一方面,在应用程序代码中检测空值并根据空值与非空值决定要做什么也不是完全干净的 单个语句的一个优点是,到服务

我正在处理其他人的PHP代码,并一次又一次地看到这种模式:

(伪代码)


如果另一个表中没有相关行,那么代码需要进行分支,但是在单个SELECT语句中执行左连接是否可以做得更好?我是否错过了一些性能优势?可移植性问题?还是我只是吹毛求疵?

我同意你的观点-一个SQL会更好

将SQL DBMS视为ISAM文件系统,一次从一个表中进行选择,这是一种危险。在外部联接中使用单个SELECT可能更干净。另一方面,在应用程序代码中检测空值并根据空值与非空值决定要做什么也不是完全干净的

单个语句的一个优点是,到服务器的往返次数更少,特别是在每次需要其他结果时动态准备SQL时


因此,平均而言,单个SELECT语句更好。它为优化器提供了一些事情要做,并且避免了它变得太无聊。

在我看来,您所说的是相当有效的-为什么在一个可以做的时候对数据库发出两个调用-除非两个记录都作为对象单独需要(?)

当然,虽然在一次调用中从数据库中提取所有字段并将字段分离到两个单独的对象中可能不是那么简单,但这确实意味着您只依赖数据库进行一次调用,而不是两次调用

将其作为查询阅读会更好:

Select a.blah1, a.blah2, b.something From foo a Left Join foo2 b On a.foreign_key = b.key Where a.Key = bar;
通过这种方式,您可以一次检查您得到的结果,并让数据库在一次查询而不是两次查询中完成所有繁重的工作


是的,我觉得你说的似乎是对的。

这绝对是错的。你无缘无故地第二次越过电线。DBs在他们的问题空间非常快。连接表就是其中之一,您将从第二个查询中看到更多性能下降,然后是连接。除非您的表空间是数亿条记录,否则这不是一个好主意。

考虑到在一个数据库命中中,您拥有所需的所有数据,使用一条SQL语句在99%的情况下性能会更好。不确定在这种情况下是否正在动态创建连接,但这样做是否代价高昂。即使这个过程如果重用现有的连接,DBMS也不会得到优化,查询是最好的方式,也不会真正利用这些关系

出于性能原因,我所能看到的唯一方法是,如果外键检索的数据量很大,并且只有在某些情况下才需要。但是在您描述的示例中,如果它存在,则只会抓住它,因此情况并非如此,因此不会获得任何性能。

所有这些的唯一“问题”是,要处理的结果集是否包含大量联接,甚至嵌套联接

我已经有过两三个实例,其中我要继承的原始查询由一个查询组成,该查询中有很多连接,SQL需要花费很长的时间来准备语句

我回到过程中,利用一些表变量(或临时表),将查询分解为许多较小的单选择类型语句,并以这种方式构造最终结果集

这次更新极大地将响应时间缩短到了几秒钟,因为执行许多简单的“一次性”检索必要的数据更容易


这里我不是为了反对而反对,只是想指出,为了解决类似的问题,代码可能被分解到了这样一个粒度级别。

最可能的解释是,开发人员根本不知道外部联接是如何工作的。这是很常见的,即使是在对自己的专业非常有经验的开发人员中也是如此

还有一个广为流传的神话是“带有连接的查询速度很慢”。因此,许多开发人员不惜一切代价盲目地避免连接,甚至到了运行多个查询的极限,其中一个查询会更好


避免连接的神话就像是说我们应该避免在应用程序代码中编写循环,因为多次运行一行代码显然比一次运行慢。更不用说
++i
的“开销”和测试
i单个SQL查询将带来更高的性能,因为SQL server(有时不共享同一位置)只需要处理一个请求,如果要使用多个SQL查询,则会引入大量开销:

执行更多CPU指令, 向服务器发送第二个查询, 在服务器上创建第二个线程, 执行可能的更多CPU指令 在服务器上,销毁第二个线程 在服务器上,发送第二个结果 回来


在某些特殊情况下,性能可能会更好,但对于简单的事情,您无法通过多做一点工作来获得更好的性能。

没有足够的信息来真正回答这个问题。我曾经在应用程序中工作过,由于一个原因减少查询计数,由于另一个原因增加查询计数,这两种方法都可以提高性能。在同一个应用程序中


对于表大小、数据库配置和查询外部表的频率的某些组合,执行这两个查询可能比左联接快得多。但是经验和测试是唯一能告诉你这一点的。带有中等大小表的MySQL似乎对这种IME很适应。在一个表上执行三个查询通常比一个查询连接三个表要快得多。我已经看到了一个数量级的加速。

执行简单的两表联接通常是解决此问题域的最佳方法,但是根据表和索引的状态,在某些情况下,执行两个select语句可能会更好
Select a.blah1, a.blah2, b.something From foo a Left Join foo2 b On a.foreign_key = b.key Where a.Key = bar;