分享

Impala基础语法(一)

 jasonbetter 2018-05-25

Impala基础语法(一)
 1.1 Impala服务组件 
1.1.1 Impala Deamon 
    该进程运行于集群每个节点的守护进程,是Impala的核心组件,每个节点该进程的名称为 impalad 。 
    > ps -ef|grep impalad 
      负责读取数据文件;接受来自impala-shell、Hue / JDBC/ODBC的查询请求,与其他节点并行分布式工作, 
      并将本节点的查询结果返回给中心协调者节点(建议使用JDBC/ODBC接口以round-robin的方式将每个查询提交的不同节点 impalad上)。 
1.1.2 Impala Statestore 
        Statestore 搜集集群中 impalad 进程节点的健康状况,并不断的将健康状况结果转发给所有的 impalad 进程节点. 
    > ps -ef|grep statestored 
      一个 impala 集群只需要一个 statestore 进程节点。 Statestore的目的:在集群故障时对 impalad进程节点同步信息, 
1.1.3 Impala Catalog 
    当 Impalad 集群中执行SQL 语句会引起元数据变化时,catalog服务负责将这些变化推送到其他 impalad进程节点上。 
1.1.1 搜集信息 
    hive> analyze table; 
    impala> compute stats;  
第四章 SQL语句 
2.1 注释 --  /* .. */ 
2.2 数据类型 
    BIGINT、BOOLEAN、FLOAT、INT、REAL(DOUBLE)、 
    SMALLINT、2字节的整型; TINTYNT、1字节的整型、  
    STRING、不能直接将STRING转成BOOLEAN,但是可以使用CASE表达式针对不同的STRING数据返回TRUE/FALSE 
            > select cast("123" as int);//返回123 
            > select cast(true as int);//返回1 
            > select cast(false as int);//返回0 
    TIMESTAMP、> select cast('1966-07-30' as timestamp);、、返回1966-07-30 00:00:00、 Now()  
2.2.1 表达式 where * BETWEEN 上限值 AND 下限值; 
    IN、> select * from test where a in("a","abc");//传入的值(a) 只要与期中的任意一个值匹配,就会返回RURE。//返回a abc 
    IS NULL、> select * from test where a is not null;//判断给定的值是否为空 
    LIKE、> select * from test where a like 'ab_'; //比较string数据,_匹配单个字符,%匹配多个字符。 
    REGEXP/reglike、> select * from test where a regexp 'a.*'; //用来检查一个值是否与一个正则表达式相匹配.、、返回a ab abc 
2.5 AS 别名 ; 原始的名后紧跟别名也可以; 可为表、列、join结果集等指定更直观的别名 
2.5.2 标识符,大小写不敏感   
2.6 SQL语句子集--DDL数据定义语言 
       2.6.1> alter table old_name rename to new_name;  
        //通过在表名前指定数据库,可以把一张表从一个数据库 移动 到另一个数据库。 
        > creat database d1; 
        > creat database d2; 
        > creat database d3; 
        > use d1; 
        > creat table mobile(x int);  
        > use d2; 
        > alter table d1.mobile rename to mobile; 
        > use d1 ; 
        > alter table d2.mobile rename to d3.mobile; 
        > use d3; 
        > show tables;  //出现了mobile表 
    > alter table ** set location 'hdfs_path_directory'; //改变 Impala的表对应的数据文件的物理位置 
    > alter table ** set fileformat {...}; //改变底层数据文件格式 
    > alter table ** set serdeproperties ('serialization.format' = ',' , 'field.delim' = ','); //改变已存在的表/分区的分隔符 
    $ hdfs dfs -ls /user/hive/warehouse/表名     
    $ hdfs dfs -cat /user/hive/warehouse/表名/****.0   //查看表内容 
        > alter table ** add columns (defs_column);   //可以一次添加多个列 
        > alter table ** replace columns (defs_column);  //定义新的列 
        > alter table ** change  old_col  new_col  new_spec; //重命名列  
        > alter table ** drop * ;                        //只能一次删除一列 
   只有针对分区表才能进行添加或者删除分区操作。 
2.6.2 ALTER VIEW 
    只改变元数据信息  
    > creat table t2 like t1; 
    > creat view v1 as select ... 
    > desc formatted v1;  
2.6.3 compute stats 
    > show table/cloumn stats **; //在运行 compute stats ** ;之后,show stats 可以显示更多的信息 
2.6.4 creat database 
2.6.5 creat function 
   UDF:每次对单行调用返回一行的标量自定义函数。 
   UDA:对多行进行调用返回单行结果,用户自定义聚集函数。 
   通常,UDA与group by 结合将一个很大的结果集聚合成一个很小的结果集,甚至整个表进行值汇总得到一行记录。 
    > creat aggregate funtion [if not exists] [db_name.] *** ( , , ,); //aggregate创建UDA 
2.6.6 creat table 
    外部表:删除时,不会删除数据文件。 
    partitioned by 子句将一句一列或多列的值将数据文件分开存放。 
    stored as 子句指定底层存储的数据文件的格式。 
    escaped by 选择一个从未出现过的字符作为转义字符,并把它放在字段内分隔符实例之前。如使用\ : > .. escaped by '\\'  
    > creat table t2 like t1 stored as parquet; //克隆表 
    tblproperties: 指定元数据的属性。 
    with serdeproperties: 指定键值对,来指定表的 SerDe 属性。 
2.6.11 删除表  
2.6.13  
    > explain ...; 返回一个语句的执行计划 
    compute stats *;执行分析之后,explain能够显示为优化查询提供帮助的更为详细的信息。 
    并发考虑: 
        insert into 如果插入失败,插入期间数据被临时存放的数据文件和子目录不会被删除,需要使用 hdfs dfs -rm -r 跟工作目录的全目录删除。 
    > insert overwrite t1 values(,,,),(,,,); 可以将带有具体列值得行插入到表中。值需与表定义的列顺序相同,对于不想插入数据的列,指定NULL。 
2.6.14 invalidate metadata 比 refresh 成本更高。 
    invalidate metadata 会强制元数据过期,这样下次表被引用时元数据会重新加载。对于一个超大表 invalidate metadata 将会消耗大量的时间。 
    refresh 可能可以避免不可预知的延迟。 
    describe 会更新该表最新元数据信息,也会避免下次查询由于重新加载元数据带来的延迟。  
     运行impalad-shell时 -r  :会刷新元数据信息保持最新。多分区 大表不介意使用。-refresh_after_connect 
2.6.16 移动数据文件 
    > load data inpath '/.../..' [overwrite] into table t1; // '移动数据文件' 不是拷贝哟,目前只支持从HDFS中加载数据。 
    加载一个目录下所有数据文件时,需要保证数据文件位于该目录之下,而不是嵌套的子目录下。 
    shell脚本生成几个包含数字串的文件,将文件上传到HDFS上。  
    > creat table t1 (s string); 
    > load data inpath '/dir/thousand_strings.txt' into table t1; 
    > load data inpath '/dir/thousand_strings.txt' into table t1; //报错!因为文件已经不存在了 
    $ hdfs dfs -ls /user/hive/warehouse/.../t1
 
2.6.18 SELECT 
    1.SQL-92 风格JOIN:查询中显示指定jion 关键字,使用 on 或 using 指定哪些列作为连接键。 
        > select t1.c1, t2.c2 from t1 JOIN t2 
               ON t1.id = t2.id and t1.type = t2.type  /*该句或者*/   USING (id, type) 
                  where t1.c1 > 100;   //USING (id, type)用于各表关联列具有相同名称的情况。 
    2.SQL-89 风格JOIN: 用逗号分隔用到的表,用 where 条件关联列进行等值比较。 
                        易使用,也很容易由于删除某些 where子句导致连接无法工作。 
        > select t1.c1, t2.c2 from t1, t2 
               WHERE t1.id = t2.id and t1.type = t2.type 
                  AND t1.c1 > 100; 
    1.自连接 
            对某张表 不同列 进行关联查询 以展示数据之间的父子关系或树形结构。  
            无需显式指定自连接关键字,只要对 一张表 指定不同的 别名,看作两张表即可。 
        > select t1.id, t2.parent, t1.c1, t2.c2 from a t1,a t2 
          where t1.id = t2.parent;                                   // 不能理解 
    2.笛卡尔连接 
            不能用于 ON子句,和: 
                            > select ... from t1 JOIN t2; 
                            > select ... from t1, t2; 
            只用于 CROSS JOIN,或可以用 where子句进行过滤: 
                            > select ... from t1 CROSS JOIN t2; 
                            > select ... from t1 CROSS JOIN t2 WHERE ...; 
    5.内连接 
            是最常用的类型,结果集包含所有参与连接的表中匹配的列,这些列具有满足在不同表之间关联列的等值匹配。 
            如果参与连接的表具有相同的列名,则需要使用完全限定名 或者列别名进行引用。支持SQL-89/92。  
        > select t1.id, c1,c2 from t1,t2 WHERE t1.id = t2.id; 
        > select t1.id, c1,c2 from t1 JOIN t2 ON t1.id = t2.id; 
        > select t1.id, c1,c2 from t1 INNER JOIN t2 ON t1.id = t2.id; 
    6.外连接 ..OUTER join 
            从左手型表(LEFT),右手型表(RIGHT),全外连接表(FULL) 获取所有的 行数据 
            如果外连接的表中没有与其他表关联匹配的数据,结果集中相关列会被置为 NULL。 
            用的是 SQL-92语法,(join不能用逗号代替),不支持 SQL-89的连接语法。 
        > select * from t1 LEFT OUTER JOIN t2 on t1.id = t2.id;
        > select * from t1 RIGHT OUTER JOIN t2 on t1.id = t2.id;
        > select * from t1 FULL OUTER JOIN t2 on t1.id = t2.id; 
    7.等值连接和非等值连接 
            Impala默认进行等值连接查询。inner outer full semi 都是。 
            可以使用比较运算符实现 非等值连接,可以避免产生超出资源限制的超大结果集。 
            如果执行的 非等值链接产生的结果集大小可以接受,可使用 cross join ,并且在 where子句中进行额外的比较操作。  
        > select .. from t1 CROSS JOIN t2 WHERE t1.total > t2.maximum_price; 
    8.Impala不支持自然连接和反连接 
    9.在如下情况使用连接查询:
      。当需要从不同物理上独立存储的表进行关联获取数据时。
      。将数据归一化,连接查询允许我们减少数据复制,将不同的数据存储在不同的表中。
      。对于那些很少使用的某些列,我们可以将其移动到其他表中以减少大部分查询的负载。
      。减少歧义on where中
        > select t1.c1 as first_id, t2.c2 as second_id from t1 join t2 on first_id = second_id;
        > select fact.custno, dimension.custno from customer_data as fact join customer_address as dimension using (custno);
    10.order by 排序
        这是一个代价非常高的操作,因为在排序之前,整个结果集需要传输到一个节点上进行排序,需要更多的内存容量。 
        order by .. [ASC | DESC] [NULLS FIRST | NULLS LAST]  指定升序/降序,null值位于结果集开头还是结尾。 
        Impala-shell中对一个会话所有的查询设置默认limit:
                                                        > set DEFAULT_ORDER_BY_LIMIT=...
        也可以在启动Inpala进程时指定
            -default_query_options default_order_by_limit=...在实例级别进行限制。 
    11.group by 
        需要使用像 count()、sun()、avg()、min()、max()这样的聚集函数。 
        > select **,sum(s1) as s from *** group by ***  
           order by sum(s1) desc limit 5;
    12.having 
        对带有group by 子句的select查询执行过滤操作,它过滤的是 聚集函数运算的结果,而不是原始数据的行。 
        > select ss_item as item, 
            count(ss_item) as time_p, 
            sum(ss_11) as **, 
          from ** 
            group by ss_item     //用的是原始数据 
            having item >= 100   //用的是别名 
            order by sum(ss_11)  //用的是原始数据 
            limit 5; 
    13.offset 
        查询自逻辑第一行之后的某行开始返回结果。经常结合order by 、limit一起使用。 
        > select x from numbers order by x limit 5 offset 5; //从5开始对缓存的结果集进行分页显示在页面上 
    14.union 
        合并多个查询结果集。就好像是使用了 distinct一样。 
        > select**1  union [distinct | all]  select**2     //去重. 不使用all的union耗更多内存和时间。 
    15.with 
        放在 select之前,用于为 复杂表达式定义一个别名。 
        方便维护、可读性强、提高兼容性。 
        > with t1 as (select 1), t2 as (select 2)  
            select * from t1 union all select * from t2; 
    16.hints 
        可以更好的从底层调整SQL查询的工作方式。 
        对于那些丢失了统计信息或者其他因素导致查询成本异常昂贵时,作为临时解决方案。 
        使用【】将特定的hints括起来使用。 
        explain可以确认一个特定查询使用了什么关联策略。 
        [shuffle]:join使用分区技术,该方式对于处理 大表与大表之间的关联非常有效。 
        [broadcast]:join使用广播技术,将右手型表的所有内容发送到与之关联的所有节点上。对于处理 大表与小表 之间的关联非常有效。 
        > select ... from d1  join [broadcast]d2 on ..=..; 
    17.show..; use..; 
        > show databases like 'd*'; 
        > show tables in default 't*'; 
        > show functions in **; //显示的是UDFs, 查看内嵌函数的定义 
        > show aggregate functions in **; //UDAFs 
        > show table/column stats db.tb; //对于调整和诊断性能,大表和复杂连接查询非常重要 
        启动impala-shell时连接到特定数据库: 
            impala-shell -d db_name   //-d 选项对于运行SQL脚本非常有用,使用之后无需把USE语句硬编码在SQL脚本中。 

2.7 内嵌函数 
    聚集函数不会返回Null值,会忽略掉列中null值。 
    cast(10 as string) 类型转换 
    concat('123', cast(45 as string), '6') 字符串连接 
    case a when b then c [when d then e].. end  将表达式与多个可能进行比较,如果匹配到则返回相应结果。 
    pid()返回会话连接到的impala进程ID。 
    user()返回连接到impala进程的Linux用户名。 
    current_database()返回当前数据库名称。 
    version()...

Impala 表指向已存的数据文件


DROP TABLE IF EXISTS tab1;
-- EXTERNAL子句表示数据位于 Impala 数据文件中央位置之外
-- 并且 Impala 中表删除后,原始数据文件仍然存在
-- 我们假定 LOCATION 子句中指定的目录是存在的
CREATE EXTERNAL TABLE tab1
(
   id INT,
   col_1 BOOLEAN,
   col_2 DOUBLE,
   col_3 TIMESTAMP
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/user/cloudera/sample_data/tab1';

DROP TABLE IF EXISTS tab2;
-- TAB2 同 TAB1 一样都是外部表
CREATE EXTERNAL TABLE tab2
(
   id INT,
   col_1 BOOLEAN,
   col_2 DOUBLE
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/user/cloudera/sample_data/tab2';

DROP TABLE IF EXISTS tab3;
-- 不使用 EXTERNAL 子句表示数据统一由 Impala 管理
-- 这里不再在创建表时候读取已存在的数据文件,而是创建表之后再载入数据
CREATE TABLE tab3
(
   id INT,
   col_1 BOOLEAN,
   col_2 DOUBLE,
   month INT,
   day INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

将外部分区表指向 HDFS 目录结构

    建立 文件

$ hdfs dfs -mkdir -p /user/impala/data/external_partitions/year=2013/month=08/day=01/host=host1
$ hdfs dfs -mkdir -p /user/impala/data/external_partitions/year=2013/month=07/day=28/host=host1
$ hdfs dfs -mkdir -p /user/impala/data/external_partitions/year=2013/month=07/day=28/host=host2
$ hdfs dfs -mkdir -p /user/impala/data/external_partitions/year=2013/month=07/day=29/host=host1
$ hdfs dfs -put dummy_log_data /user/impala/data/logs/year=2013/month=07/day=28/host=host1
$ hdfs dfs -put dummy_log_data /user/impala/data/logs/year=2013/month=07/day=28/host=host2
$ hdfs dfs -put dummy_log_data /user/impala/data/logs/year=2013/month=07/day=29/host=host1
$ hdfs dfs -put dummy_log_data /user/impala/data/logs/year=2013/month=08/day=01/host=host1
  

生成外部表

create external table logs (field1 string, field2 string, field3 string)
  partitioned by (year string, month string, day string, host string)
  row format delimited fields terminated by ','
  location '/user/impala/data/logs';

 ALTER TABLE 语句标识每一个分区。

alter table logs add partition (year="2013",month="07",day="28",host="host1")
alter table logs add partition (year="2013",month="07",day="28",host="host2");
alter table logs add partition (year="2013",month="07",day="29",host="host1");
alter table logs add partition (year="2013",month="08",day="01",host="host1");


https://blog.csdn.net/zhaodedong/article/details/52251526


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多