zoukankan      html  css  js  c++  java
  • joins与where的关系

    • inner join 的where和on是一样的
    • 联接在出现子句之前发生。因此,如果您想限制联接的输出,则需求应在 WHERE 子句中,否则应在 JOIN 子句中。这个问题的一大困惑是分区表:
    SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key)
      WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

    将在 b 上加入 a,生成 a.val 和 b.val 的列表。但是,WHERE 子句也可以引用联接输出中的 a 和 b 的其他列,然后将其过滤掉。但是,只要 JOIN 中的一行找到 a 的键而 b 的键都没有,则 b 的所有列都将为 NULL, 包括 ds 列 。

    这就是说,您将过滤掉没有有效 b.key 的所有联接输出行,因此,您超出了 LEFT OUTER 的要求。换句话说,如果您在 WHERE 子句中引用 b 的任何列,则联接的 LEFT OUTER 部分无关紧要。相反,在进行外部联接时,请使用以下语法:

    SELECT a.val, b.val FROM a LEFT OUTER JOIN b
      ON (a.key=b.key AND b.ds='2009-07-07' AND a.ds='2009-07-07')

    ..结果是对联接的输出进行了预过滤,对于具有有效 a.key 但不匹配 b.key 的行,您将不会遇到后过滤麻烦。相同的逻辑适用于 RIGHT 和 FULL 连接。

    • 连接不是可交换的!联接是左关联的,无论它们是 LEFT 联接还是 RIGHT 联接。
    SELECT a.val1, a.val2, b.val, c.val
      FROM a
      JOIN b ON (a.key = b.key)
      LEFT OUTER JOIN c ON (a.key = c.key)

    ...首先在 b 上加入 a,将 a 或 b 中所有没有其他键的东西都扔掉。然后将精简表连接到 c。如果 a 和 c 中都存在一个键但 b 中不存在键,这将提供不直观的结果:整个行(包括 a.val1,a.val2 和 a.key)都被删除在“ a JOIN b”步骤中,因为不在 b。结果中没有 a.key,因此当它与 c 一起左移时,由于没有 c.key 与 a.key 匹配,因此 c.val 不会加入(因为 a 中的行已删除) )。同样,如果这是一个 RIGHT OUTER JOIN(而不是 LEFT),我们最终会得到一个更奇怪的效果:NULL,NULL,NULL,c.val,因为即使我们将 a.key = c.key 指定为联接键,我们删除了所有与第一个 JOIN 不匹配的行。
    为了获得更直观的效果,我们应该改为 FROM FROM c 左外连接 a ON(c.key = a.key)左外连接 b ON(c.key = b.key)。

    • LEFT SEMI JOIN 以有效的方式实现了不相关的 IN/EXISTS 子查询语义。从 Hive 0.13 开始,使用subqueries支持 IN/NOT IN/EXISTS/NOT EXISTS 运算符,因此这些 JOIN 中的大多数不再需要手动执行。使用 LEFT SEMI JOIN 的限制是只能在连接条件(ON 子句)中引用右侧表,而不能在 WHERE 或 SELECT 子句等中引用。
    SELECT a.key, a.value
      FROM a
      WHERE a.key in
       (SELECT b.key
        FROM B);

    可以重写为:

    SELECT a.key, a.val
       FROM a LEFT SEMI JOIN b ON (a.key = b.key)
    • 如果除一个要连接的表之外的所有表都很小,则可以将其作为仅 Map 作业执行。查询
    SELECT /*+ MAPJOIN(b) */ a.key, a.value
      FROM a JOIN b ON a.key = b.key

    不需要减速器。对于 A 的每个 Map 器,B 都会被完全读取。限制是不能执行 a FULL/RIGHT OUTER JOIN b 。

    • 如果要联接的表在联接列上进行了存储桶化,并且一个表中的存储桶数是另一表中存储桶数的倍数,则这些存储桶可以彼此连接。如果表 A 有 4 个存储桶,表 B 有 4 个存储桶,则以下联接
    SELECT /*+ MAPJOIN(b) */ a.key, a.value
      FROM a JOIN b ON a.key = b.key

    只能在 Map 器上完成。并非完全为 A 的每个 Map 器获取 B,而是仅获取所需的存储桶。对于上面的查询,A 的 Map 器处理存储桶 1 将仅获取 B 的存储桶 1.这不是默认行为,由以下参数控制

    set hive.optimize.bucketmapjoin = true
    
    • 如果要联接的表在联接列上进行了排序和存储,并且它们具有相同数量的存储桶,则可以执行排序合并联接。对应的存储桶在 Map 器处相互连接。如果 A 和 B 都有 4 个存储桶,
    SELECT /*+ MAPJOIN(b) */ a.key, a.value
      FROM A a JOIN B b ON a.key = b.key

    只能在 Map 器上完成。 A 的存储桶的 Map 器将遍历 B 的对应存储桶。这不是默认行为,需要设置以下参数:

    set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
      set hive.optimize.bucketmapjoin = true;
      set hive.optimize.bucketmapjoin.sortedmerge = true;

    MapJoin Restrictions

    • 如果除一个要连接的表之外的所有表都很小,则可以将其作为仅 Map 作业执行。查询
    SELECT /*+ MAPJOIN(b) */ a.key, a.value
      FROM a JOIN b ON a.key = b.key

    不需要减速器。对于 A 的每个 Map 器,B 都会被完全读取。

    • 不支持以下内容。

    • union 后跟一个 MapJoin

      • 横向视图后跟一个 MapJoin

      • 减少接收器(分组依据/加入/排序依据/集群依据/分发依据),其次是 MapJoin

      • MapJoin 之后是 union

      • MapJoin,然后加入

      • MapJoin 其次是 MapJoin

    • 配置变量 hive.auto.convert.join(如果设置为 true)会在运行时自动将联接转换为 mapjoins,应使用它代替 mapjoin 提示。 mapjoin 提示仅应用于以下查询。

    • 如果对所有 Importing 进行了存储分区或排序,则该联接应转换为存储分区的 Map 端连接或存储分区的排序合并联接。

    • 考虑在不同的键上使用多个 mapjoin 的可能性:

    select /*+MAPJOIN(smallTableTwo)*/ idOne, idTwo, value FROM
      ( select /*+MAPJOIN(smallTableOne)*/ idOne, idTwo, value FROM
        bigTable JOIN smallTableOne on (bigTable.idOne = smallTableOne.idOne)                                                   
      ) firstjoin                                                             
      JOIN                                                                  
      smallTableTwo ON (firstjoin.idTwo = smallTableTwo.idTwo)

    不支持上述查询。如果没有 mapjoin 提示,则以上查询将作为 2 个仅 map 作业执行。如果用户事先知道 Importing 足够小以适合内存,则可以使用以下可配置参数来确保查询在单个 map-reduce 作业中执行。

    • hive.auto.convert.join.noconditionaltask-Hive 是否启用基于 Importing 文件大小的关于将普通联接转换为 mapjoin 的优化。如果启用此参数,并且 n 向联接的表/分区的 n-1 个大小的总和小于指定的大小,则该联接将直接转换为 mapjoin(没有条件任务)。

      • hive.auto.convert.join.noconditionaltask.size-如果关闭了 hive.auto.convert.join.noconditionaltask,则此参数不起作用。但是,如果启用了该连接,并且 n 向联接的表/分区的 n-1 个大小的总和小于此大小,则该联接将直接转换为 mapjoin(没有条件任务)。默认值为 10MB。
    如有错误,恳求读者指出,发送到wu13213786609@outlook.com。
  • 相关阅读:
    CSS基础
    AXIS2 开发笔记
    Tomcat和Weblogic下ajax或get中文乱码
    Jetty和Tomcat的选择:按场景而定
    分页
    windows linux 下,获取java项目绝对路径的方法
    oracle SQL
    ArrayUtils
    Xcode 调试技巧
    Core Data持久化数据存储(1)
  • 原文地址:https://www.cnblogs.com/WLCYSYS/p/14672173.html
Copyright © 2011-2022 走看看