• HIVE QL 杂记


      最近要处理用户访问日志,需要从HIVE中取数据,写了一些HIVE QL,有一点小感想,记录在此。

      1. 临时表

      在HIVE中进行多表连接时,可以给一些临时表命名,这样有助于理清查询语句之间的逻辑,格式为: 

    #将从table表中取出的a,b列组成的临时表命名为t
    (SELECT a,b FROM table) t

      在一些情况下,必须采用命名临时表的方法,比如我们在处理日志时,可能希望从日志的某个字段中抽取出某些有用的信息X,然后对X进行分组(GROUP BY X)。假设希望从URL中抽取出用户的ID,采用以下正则表达式regexp_extract(url,'uid=([0-9]+)',1),我们可能会写成以下形式:

    #错误的HIVE QL,会报编译错误:找不到X列
    SELECT regexp_extract(url,'uid=([0-9]?)',1) X FROM logs GROUP BY X

      这个时候HIVE会报语法错误,找不到X列。这种情况下,我们只能先抽取信息,将抽取出的信息组成的临时表进行命名,然后对这个表进行分组:

    #首先将抽取信息组成的临时表命名为L,然后对临时表进行分组
    SELECT L.X FROM(SELECT regexp_extract(url,'uid=([0-9]?)',1) FROM logs) L GROUP BY L.X

      2. 快速查询

      存储在HIVE中的表都是非常非常巨大的,所以加快查询速度非常重要。这方面的技巧非常多,在此只记录一下自己的一些经验。

      (1). 如果希望随机取出table表中的N条记录看一下,可以使用以下语句,很多情况下根本不会执行MAP/REDUCE语句,可能是直接从表元数据中取数据。

    #快速从table表中取随机N条数据,可能不会触发M/R
    SELECT * FROM table LIMIT N

      (2). 如果在创建表的时候根据某个列Y进行了分区(PARTITION),则在执行SELECT操作的时候,在WHERE子句中加入Y="xxx"可以显著地减少查询语句的执行时间。每个分区实际上是在HDFS当中表文件夹下面的一个子文件夹,在WHERE子句中使用分区列可以显著地减少搜索空间。详细信息见[2]。

      (3). 在执行多表连接时,尽量把小表放在左侧,一来左侧的表会被放入内存,这样将小表放在前面可以有效的防止内存泄露,而来首先连接小表会使得生成的临时表较小,有助于整个查询计划的加速,这点和SQL是一样的。

      3. 改写exist in

      HIVE QL不支持exist in,但是我们可以用其他语句进行改写:

    #带exist in的SQL语句
    SELECT t1.X FROM t1 WHERE t1.X EXIST IN (SELECT t2.X FROM t2)
    #改写后的HIVE QL语句
    SELECT t1.X FROM t1 LEFT JOIN t2 ON t1.X=t2.X WHERE t1.x!=NULL

      参考文献:

      [1]. 写好HIVE程序的五个提示

      [2]. Hive Tips

      [3]. HIVE0.5 中Partition简述

  • 相关阅读:
    Linux就该这么学--Shell脚本基本应用
    Linux就该这么学--了解Shell脚本
    Linux就该这么学--命令集合11(配置系统相关信息)
    解決 centos -bash: vim: command not found
    Linux就该这么学--命令集合10(vim编辑器)
    Linux就该这么学--命令集合9(环境变量)
    html5 浏览器端数据库
    加密技术---仿射密码
    数组的运用、排序
    面试题参考
  • 原文地址:https://www.cnblogs.com/kemaswill/p/2850410.html
Copyright © 2020-2023  润新知