当前位置:  开发笔记 > 数据库 > 正文

是否需要正确的加入?

如何解决《是否需要正确的加入?》经验,为你挑选了4个好方法。

是否存在任何需要RIGHT JOIN的查询,或者是否可以使用LEFT JOIN重写它们?

更具体地说,如果没有正确的连接,你如何重写这个(我猜是没有任何子查询或其他幻想):

SELECT *
FROM t1
LEFT JOIN t2 ON t1.k2 = t2.k2
RIGHT JOIN t3 ON t3.k3 = t2.k3



1> Joel Coehoor..:

您可以随时重新编写它们以获得相同的结果集.但是,有时执行计划可能在很大程度上(性能)有所不同,有时正确的连接让您以更有意义的方式表达查询.

让我来说明性能差异.程序员倾向于根据一次发生的sql语句来思考.但是,通过一系列步骤保持一个复杂查询的心智模型是有用的,其中表通常以列出的顺序连接.所以你可能有这样的查询:

SELECT * /* example: don't care what's returned */
FROM LargeTable L
LEFT JOIN MediumTable M ON M.L_ID=L.ID
LEFT JOIN SmallTable S ON S.M_ID=M.ID
WHERE ...

服务器通常会先将WHERE子句中的任何内容应用到列出的第一个表(在本例中为LargeTable),以减少加载到内存中所需的内容.然后它将加入下一个表(MediumTable),然后加入那个表(SmallTable),依此类推.

我们想要做的是使用一种策略来解释每个联接表对结果的预期影响.通常,您希望尽可能长地保持结果集尽可能小.将该原则应用于上面的示例查询,我们发现它显然比它需要的慢得多.它从较大的集合(表格)开始并向下运行.我们想从较小的集开始并开始工作.这意味着首先使用SmallTable,这样做的方法是通过RIGHT JOIN.

这里的另一个关键是服务器通常无法知道在连接完成之前需要哪些来自SmallTable的行.因此,只有SmallTable比LargeTable小得多才能将整个SmallTable加载到内存中比从LargeTable开始的任何东西都要便宜(LargeTable是一个大表,可能是索引很好的,可能是在一个或三个字段上过滤在where子句中).

重要的是还要指出,在绝大多数情况下,优化器会查看这个并以最有效的方式处理事情,并且大多数情况下优化器会比这更好地完成这项工作.

但优化器并不完美.有时你需要帮助它:特别是如果你的一个或多个"表"是一个视图(可能是一个链接服务器!)或一个嵌套的select语句,例如.嵌套子查询也是一个很好的例子,您可能希望使用正确的连接以表达原因:它允许您移动查询的嵌套部分,以便您可以更好地分组.



2> charles bret..:

你总是可以只使用左连接......

SELECT * FROM t1
    LEFT JOIN t2 ON t1.k2 = t2.k2
    RIGHT JOIN t3 ON t3.k3 = t2.k3

是等同于:

Select * From t3 
   Left Join (t1 Left Join t2 
                  On t2.k2 = t1.k2)
      On T2.k3 = T3.K3

一般来说,我总是尝试只使用左连接,因为左连接中左边的表是输出中包含行的ALL,我喜欢把它想象,(左侧)作为"基础" "设置我正在执行cartesion产品(加入)对...所以我喜欢在SQL中首先使用它...



3> mauriciopast..:

是! 每时每刻!(不得不承认,主要是在您严格要求首先调用哪个表时使用)

关于这个主题:这是一个很好的连接视觉指南.



4> David Grant..:

这有点像询问是否需要使用大于号.使用更适合手头任务的那个.

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有