原 Impala SQL 語言元素(翻譯)html
本文來源於http://my.oschina.net/weiqingbin/blog/189413#OSC_h2_2node
摘要 http://www.cloudera.com/content/cloudera-content/cloudera-docs/Impala/latest/Installing-and-Using-Impala/ciiu_langref_sql.htmlweb
目錄[-]正則表達式
Impala SQL 語言元素(Elements)算法
Impala SQL 方言支持一組標準元素(a range of standard elements),加上許多大數據方面的擴展,用於數據加載和數據倉庫方面。sql
注意:shell
在以前的 Impala beta 版中,在 impala-shell 中每一語句結束時的分號是可選的。如今 impala-shell 支持多行命令,以便於從腳本文件中複製粘貼代碼,這樣每一語句結束時的分號是必需的。數據庫
下面章節演示了 Impala 中 SQL 語言的主要語句、子句以及其餘元素。express
繼續閱讀:apache
ALTER TABLE 語句
ALTER TABLE 語句用來修改現有表的結構或屬性。在 Impala 裏,這是一個邏輯操做,更新了 Impala 和 Hive 共用的 metastore 數據庫中表的元數據; ALTER TABLE 語句不會對實際的數據文件進行重寫、移動等操做。所以,你可能須要相應的物理文件系統操做才能實現移動數據文件到不一樣的 HDFS 目錄,重寫數據文件來包含其餘字段,或轉換成不一樣的文件格式。
重命名錶:
ALTER TABLE old_name RENAME TO new_name;
對於內部表,這一操做實際地修改了包含數據文件的 HDFS 目錄名;原始目錄將再也不存在。經過修改表名前面的數據庫名,你能夠把一個數據庫中的內部表(包括對應的數據目錄)移動到另外一個數據庫。例如:
create database d1;
create database d2;
create database d3;
use d1;
create table mobile (x int);
use d2;
-- 移動其餘數據庫中的表到當前數據庫
alter table d1.mobile rename to mobile;
use d1;
-- 移動一個數據庫中的表達哦另外一個數據庫
alter table d2.mobile rename to d3.mobile;
修改 Impala 查找表的相關數據文件的物理位置:
ALTER TABLE table_name SET LOCATION 'hdfs_path_of_directory';
指定的路徑是數據文件所在的完整路徑,或者是不存在被建立的路徑。Impala 不會建立該表名下面的額外子目錄。Impala 不會移動任意數據文件到新位置,也不會修改這一目錄下現存的數據文件。
修改 TBLPROPERTIES 和 SERDEPROPERTIES 列的鍵值對:
ALTER TABLE table_name SET TBLPROPERTIES ('key1'='value1', 'key2'='value2', ...);
ALTER TABLE table_name SET SERDEPROPERTIES ('key1'='value1', 'key2'='value2', ...);
TBLPROPERTIES 子句是將任意用戶指定數據項與特定表關聯起來的主要方法(The TBLPROPERTIES clause is primarily a way to associate arbitrary user-specified data items with a particular table)。SERDEPROPERTIES 子句設置表如何讀寫,在 Hive 中許多狀況下須要,實際在 Impala 中未使用(The SERDEPROPERTIES clause sets up metadata defining how tables are read or written, needed in some cases by Hive but not actually used by Impala)。參考 CREATE TABLE Statement 瞭解這些子句的詳細信息。參考 Setting Statistics Manually through ALTER TABLE 中的使用表屬性來微調相關表統計信息的性能的例子(for an example of using table properties to fine-tune the performance-related table statistics)。
重組表中的列:
ALTER TABLE table_name ADD COLUMNS (column_defs);
ALTER TABLE table_name REPLACE COLUMNS (column_defs);
ALTER TABLE table_name CHANGE column_name new_name new_spec;
ALTER TABLE table_name DROP column_name;
其中 column_spec 與 CREATE TABLE 語句中相同:列名,列數據類型,以及可選的列備註。你能夠一次添加多個列。不管是添加單個列仍是多個列,都須要用括號括起來。當替換列時,原有列的定義都被廢棄。你可能會在收到一組新的有不一樣數據類型或不一樣順序的列的數據文件時使用這一技術(數據文件會被保留,所以當新列與舊列不兼容時,須要在執行進一步的查詢前,使用 INSERT OVERWRITE 或 LOAD DATA OVERWRITE 語句替換全部的數據)。
你可使用 CHANGE 子句重命名某一個列,或轉換現存的列爲其餘類型,例如在 STRING 和 TIMESTAMP 之間轉換,或者在 INT 與 BIGINT 之間轉換。一次只能刪除一個列;想要刪除多個列,須要執行屢次 ALTER TABLE 語句,或者在單個 ALTER TABLE ... REPLACE COLUMNS 語句中定義一組新的列。
修改 Impala 中表指望的文件格式(To change the file format that Impala expects table data to be in):
ALTER TABLE table_name SET FILEFORMAT { PARQUET | PARQUETFILE | TEXTFILE | RCFILE | SEQUENCEFILE }
由於本操做只是修改表的元數據,對現存的數據,你必須使用 Impala 以外的 Hadoop 技術對已有的數據進行轉換。以後再在 Impala 中使用 INSERT 語句建立的數據將使用新的格式。你不能指定文本文件的分隔符;文本文件的分隔符必須是逗號。
爲了添加或刪除表的分區, 表必須已是分區表(也就是說,使用帶 PARTITIONED BY 子句建立的表)。分區是一個 HDFS 中的實際目錄,目錄名包含特定列的值(partition key,分區鍵)。假如必要,Impala 的 INSERT 語句會建立分區,所以 ALTER TABLE ... ADD PARTITION 語句的主要用途是經過移動或複製已有的數據文件到分區對應的 HDFS 目錄來導入數據。DROP PARTITION 子句用於刪除一組指定分區鍵值對應的 HDFS 目錄和對應的數據文件;例如,假如你老是分析最近 3 個月數據的價值,在每月初你就能夠刪除掉再也不須要的最老的那個分區的數據。刪除分區會減小表相關的元數據數量,減輕計算查詢計劃的複雜度,從而能夠簡化和提高分區表的查詢速度,特別是鏈接查詢。下面展現了 ADD PARTITION 和 DROP PARTITION 子句。
-- 建立一個空的分區模式的表
create table part_t (x int) partitioned by (month string);
-- 建立一個空分區,下面將從其餘源複製數據文件到這個分區
alter table part_t add partition (month='January');
-- 變動相關數據後,執行 REFRESH 語句使得數據對 Impala 可見
refresh part_t;
-- 而後,添加下一月份
alter table part_t add partition (month='February');
-- 如今再也不須要一月份數據
alter table part_t drop partition (month='January');
-- 假如表是根據月份、年份分區,執行相似語句:
-- alter table part_t drop partition (year=2003,month='January');
-- 這將須要 12 個 ALTER TABLE 語句來刪除 2003 全年的數據
分區鍵的值能夠是任意常數表達式,不須要引用標中的列(The value specified for a partition key can be an arbitrary constant expression, without any references to columns).例如:
alter table time_data add partition (month=concat('Decem','ber'));
alter table sales_data add partition (zipcode = cast(9021 * 10 as string));
使用注意:
在 ALTER TABLE 語句中,必須包括全部的分區列(Whenever you specify partitions in an ALTER TABLE statement, you must include all the partitioning columns in the specification)。
對於內部表(Impala 管理表)和外部表(數據文件在任意位置)來講,以前的絕大多數操做是一致的。惟一的列外是重命名錶;對外部表來講,相關的數據目錄不會被重命名或移動。
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
注意:
重組表和其關聯的數據文件的另外一種方法是使用 CREATE TABLE 語句建立一個與原始表不一樣的表,而後使用 INSERT 語句複製轉換或從新排序的數據到新表。ALTER TABLE 的優點是避免了數據文件的重複複製,容許你使用熟悉的 Hadoop 技術以一種節省空間的方式來重組巨大容量的數據。
語句類型: DDL
ALTER VIEW 語句
修改視圖裏的查詢,或相關的數據庫和/或視圖的名稱。
由於視圖是一種純邏輯結構(一個查詢的別名)沒有實際的數據,ALTER VIEW 只執行 metastore 數據庫中元數據的修改,不涉及 HDFS 中的任意數據文件。
ALTER VIEW [database_name.]view_name AS select_statement
ALTER VIEW [database_name.]view_name RENAME TO [database_name.]view_name
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
例子:
create table t1 (x int, y int, s string);
create table t2 like t1;
create view v1 as select * from t1;
alter view v1 as select * from t2;
alter view v1 as select x, upper(s) s from t2;
執行 DESCRIBE FORMATTED 語句來查看視圖的定義,這將顯示原始 CREATE VIEW 中的查詢:
[localhost:21000] > create view v1 as select * from t1;
[localhost:21000] > describe formatted v1;
Query finished, fetching results ...
+------------------------------+------------------------------+----------------------+
| name | type | comment |
+------------------------------+------------------------------+----------------------+
| # col_name | data_type | comment |
| | NULL | NULL |
| x | int | None |
| y | int | None |
| s | string | None |
| | NULL | NULL |
| # Detailed Table Information | NULL | NULL |
| Database: | views | NULL |
| Owner: | cloudera | NULL |
| CreateTime: | Mon Jul 08 15:56:27 EDT 2013 | NULL |
| LastAccessTime: | UNKNOWN | NULL |
| Protect Mode: | None | NULL |
| Retention: | 0 | NULL |
| Table Type: | VIRTUAL_VIEW | NULL |
| Table Parameters: | NULL | NULL |
| | transient_lastDdlTime | 1373313387 |
| | NULL | NULL |
| # Storage Information | NULL | NULL |
| SerDe Library: | null | NULL |
| InputFormat: | null | NULL |
| OutputFormat: | null | NULL |
| Compressed: | No | NULL |
| Num Buckets: | 0 | NULL |
| Bucket Columns: | [] | NULL |
| Sort Columns: | [] | NULL |
| | NULL | NULL |
| # View Information | NULL | NULL |
| View Original Text: | SELECT * FROM t1 | NULL |
| View Expanded Text: | SELECT * FROM t1 | NULL |
+------------------------------+------------------------------+----------------------+
Returned 29 row(s) in 0.05s
語句類型: DDL
AVG 函數
返回一組數字的均值的聚合函數。它惟一的參數是一個數值列、或者基於列返回數值的函數或表達式(Its single argument can be numeric column, or the numeric result of a function or expression applied to the column value)。指定列中值爲 NULL 的行將被忽略。假如表爲空,或者輸入 AVG 的值都是 NULL,則 AVG 返回 NULL。
當查詢包含 GROUP BY 子句,返回每個分組組合的一個值。
返回類型: DOUBLE
例子:
-- 計算全部非空行的均值
insert overwrite avg_t values (2),(4),(6),(null),(null);
-- 上面表中的均值是 4: (2+4+6) / 3. 兩個 NULL 值被忽略
select avg(x) from avg_t;
-- 計算特定行的均值(Average only certain values from the column)
select avg(x) from t1 where month = 'January' and year = '2013';
-- 在計算均值前進行計算
select avg(x/3) from t1;
-- 在計算均值前對列進行函數運算
-- 這裏把全部 NULL 的行替換爲 0
-- 這樣值爲 NULL 的行也會做爲均值計算的因子
select avg(isnull(x,0)) from t1;
-- 對 string 列使用某些返回值爲數字的函數,而後計算均值
-- 假如某行 s 的值包含 NULL,則 length(s) 函數也返回 NULL,該行被忽略
select avg(length(s)) from t1;
-- 也能夠與 DISTINCT 和/或 GROUP BY 組合使用
-- 返回多於一個的結果
select month, year, avg(page_visits) from web_stats group by month, year;
-- 在執行計算前過濾重複的值
select avg(distinct x) from t1;
-- 執行計算後過濾輸出的值
select avg(x) from t1 group by y having avg(x) between 1 and 20;
BETWEEN 操做符
在 WHERE 子句中,將表達式與下限和上限比較。當表達式大於等於下限,而且小於等於上限,則表達式比較成功。假如上限下限互換,也就是說下限大於上限,那麼就不匹配任何值。
語法: expression BETWEEN lower_bound AND upper_bound
數據類型: 一般使用數字類型。適用於任何類型但不是很實用的 BOOLEAN(Works with any data type, although not very practical for BOOLEAN values)。 (BETWEEN false AND true 會匹配全部的 BOOLEAN 值)。必要時使用 CAST() 函數來確保下限和上限值是兼容的數據類型。假如必要的時候調用 string 或 date/time 函數來提取或轉換相關的比較部分,特別是值能夠轉換成數字的時候。
使用注意:使用短字符串操做數時要小心(Be careful when using short string operands)。以上限的字符串開始的長字符串將不被包含,由於它被認爲是大於上限(A longer string that starts with the upper bound value will not be included, because it is considered greater than the upper bound)。例如,BETWEEN 'A' and 'M' 將不會匹配字符串 'Midway'。假如必要,使用例如 upper(), lower(), substr(), trim(), 等等函數以確保比較如預期執行。
例子:
-- 返回1到6月的值,包括1跟6月.
select c1 from t1 where month between 1 and 6;
-- 返回以'A' 到 'M' 開頭的名字
-- 只檢測第一個字符以確保全部以 'M' 開頭的名稱符合
-- 進行大小寫敏感的比較以配合不一樣大小寫約定的名稱(Do a case-insensitive comparison to match names with various capitalization conventions)
select last_name from customers where upper(substr(last_name,1,1)) between 'A' and 'M';
-- 返回每月第一週的數據
select count(distinct visitor_id)) from web_traffic where dayofmonth(when_viewed) between 1 and 7;
BIGINT 數據類型
8字節的整數類型,用於 CREATE TABLE 和 ALTER TABLE 語句。
範圍: -9223372036854775808 .. 9223372036854775807。沒有無符號子類型。
轉換: Impala 自動轉換爲浮點類型(FLOAT or DOUBLE)。 使用 CAST() 函數轉換成 TINYINT, SMALLINT, INT, STRING, or TIMESTAMP。數值 N 轉換成 TIMESTAMP 時,是轉換成從 1970年1月1日開始的 N 秒。
相關信息: INT Data Type, SMALLINT Data Type, TINYINT Data Type, Mathematical Functions
BOOLEAN 數據類型
用於 CREATE TABLE 和 ALTER TABLE 語句的數據類型,表示一個單一的 true/false 的選擇。
範圍: TRUE or FALSE。不要使用引號引發 TRUE 和 FALSE 的字符值。你可使用大寫、小寫或混合格式的值。表中返回的值都是小寫的 true 或 false。
轉換: Impala 不會自動轉換其餘類型爲 BOOLEAN。可使用 CAST() 轉換任意 integer 或 float-point 類型爲 BOOLEAN: 0 表示 false,其餘非零值轉化爲 true。STRING 不能轉換爲 BOOLEAN,儘管 BOOLEAN 能夠轉換爲 STRING,其中 true 對應 '1' 而 false 對應 '0'。
相關信息: Conditional Functions
註釋
Impala 支持你們熟悉的 SQL 註釋風格:
例如:
-- 本行是表的註釋
create table ...;
/*
本仍是查詢的多行註釋
*/
select ...;
select * from t /* 這是查詢的嵌入式註釋 */ where ...;
select * from t -- 這是多行命令中的尾部註釋
where ...;
比較操做
Impala 支持你們熟悉的比較操做用於檢測相等、存在併爲列數據類型排序:
COMPUTE STATS 語句
採集關於表和相關列與分區中數據的數據量和分佈(Gathers information about volume and distribution of data in a table and all associated columns and partitions)。這些信息被存放在 metastore 數據庫中,被 Impala 用於幫助優化查詢。假設 Impala 能夠判斷表的大小,有許多或幾個的不一樣的值,那麼它能夠爲鏈接查詢或插入操做組織適當的並行操做。瞭解這一語句採集的幾種信息,參見 Table Statistics。
使用注意:
原來 Impala 依靠用戶運行 Hive ANALYZE TABLE 語句,但這一方法採集的統計信息被證實是緩慢和不可靠的。Impala 的 COMPUTE STATS 語句是從底層向上構建,以提升可用性和用戶友好度。你能夠運行一個單獨的 Impala COMPUTE STATS 語句來採集包括 table 和 column 的統計信息,而不是爲表和列的統計信息分別運行 Hive ANALYZE TABLE 語句。
COMPUTE STATS 也能夠採集 HBase 表的信息。採集的 HBase 表的統計信息與 HDFS-backed 表的有所不一樣,但當 HBase 表執行鏈接查詢時,統計信息仍被用於優化。
相關信息參見 SHOW Statement, Table Statistics, and Column Statistics。
例子:
本例中展現了 T1 和 T2 兩個表,其中 T1.ID 和 T2.PARENT 存在父子關係,有少許的不一樣的值連接。T1 是小表,而 T2 大概有 100K 行。最初,統計信息包括物理度量如文件的數量,總大小,以及定長列如 INT 類型的大小度量。未知值表示爲 -1。爲每一個表運行 COMPUTE STATS 以後,SHOW STATS 語句中有更多信息可用。假如你運行一個涉及這兩個表的鏈接查詢,你須要統計這兩個表以得到最優化的查詢。
[localhost:21000] > show table stats t1;
Query: show table stats t1
+-------+--------+------+--------+
| #Rows | #Files | Size | Format |
+-------+--------+------+--------+
| -1 | 1 | 33B | TEXT |
+-------+--------+------+--------+
Returned 1 row(s) in 0.02s
[localhost:21000] > show table stats t2;
Query: show table stats t2
+-------+--------+----------+--------+
| #Rows | #Files | Size | Format |
+-------+--------+----------+--------+
| -1 | 28 | 960.00KB | TEXT |
+-------+--------+----------+--------+
Returned 1 row(s) in 0.01s
[localhost:21000] > show column stats t1;
Query: show column stats t1
+--------+--------+------------------+--------+----------+----------+
| Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size |
+--------+--------+------------------+--------+----------+----------+
| id | INT | -1 | -1 | 4 | 4 |
| s | STRING | -1 | -1 | -1 | -1 |
+--------+--------+------------------+--------+----------+----------+
Returned 2 row(s) in 1.71s
[localhost:21000] > show column stats t2;
Query: show column stats t2
+--------+--------+------------------+--------+----------+----------+
| Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size |
+--------+--------+------------------+--------+----------+----------+
| parent | INT | -1 | -1 | 4 | 4 |
| s | STRING | -1 | -1 | -1 | -1 |
+--------+--------+------------------+--------+----------+----------+
Returned 2 row(s) in 0.01s
[localhost:21000] > compute stats t1;
Query: compute stats t1
+-----------------------------------------+
| summary |
+-----------------------------------------+
| Updated 1 partition(s) and 2 column(s). |
+-----------------------------------------+
Returned 1 row(s) in 5.30s
[localhost:21000] > show table stats t1;
Query: show table stats t1
+-------+--------+------+--------+
| #Rows | #Files | Size | Format |
+-------+--------+------+--------+
| 3 | 1 | 33B | TEXT |
+-------+--------+------+--------+
Returned 1 row(s) in 0.01s
[localhost:21000] > show column stats t1;
Query: show column stats t1
+--------+--------+------------------+--------+----------+----------+
| Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size |
+--------+--------+------------------+--------+----------+----------+
| id | INT | 3 | 0 | 4 | 4 |
| s | STRING | 3 | 0 | -1 | -1 |
+--------+--------+------------------+--------+----------+----------+
Returned 2 row(s) in 0.02s
[localhost:21000] > compute stats t2;
Query: compute stats t2
+-----------------------------------------+
| summary |
+-----------------------------------------+
| Updated 1 partition(s) and 2 column(s). |
+-----------------------------------------+
Returned 1 row(s) in 5.70s
[localhost:21000] > show table stats t2;
Query: show table stats t2
+-------+--------+----------+--------+
| #Rows | #Files | Size | Format |
+-------+--------+----------+--------+
| 98304 | 1 | 960.00KB | TEXT |
+-------+--------+----------+--------+
Returned 1 row(s) in 0.03s
[localhost:21000] > show column stats t2;
Query: show column stats t2
+--------+--------+------------------+--------+----------+----------+
| Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size |
+--------+--------+------------------+--------+----------+----------+
| parent | INT | 3 | 0 | 4 | 4 |
| s | STRING | 6 | 0 | -1 | -1 |
+--------+--------+------------------+--------+----------+----------+
Returned 2 row(s) in 0.01s
COUNT 函數
返回知足必定條件記錄的行數或非空行的行數的聚合函數:
當查詢中包含 GROUP BY 子句時,we
Return type: BIGINT
Examples:
-- 表中有多少行,不關心是否有 NULL 值
select count(*) from t1;
-- 表中有多少 c1 列的值不爲空的行
select count(c1) from t1;
-- 計算知足條件的行數
-- 另外, * 包括 NULL, 所以 COUNT(*) 可能比 COUNT(col) 的值大.
select count(*) from t1 where x > 10;
select count(c1) from t1 where x > 10;
-- 能夠與 DISTINCT 和/或 GROUP BY 操做聯合使用
-- 聯合使用 COUNT 和 DISTINCT 查找惟一值的個數
-- 在 COUNT(DISTINCT ...) 語法中必須使用列名而不是 *
-- c1 包含空值的行不會統計
select count(distinct c1) from t1;
-- c1 或 c2 中包含空值的每一行都不會統計(Rows with a NULL value in _either_ column are not counted)
select count(distinct c1, c2) from t1;
-- 返回多個結果
select month, year, count(distinct visitor_id) from web_stats group by month, year;
CREATE DATABASE 語句
在 Impala 裏,數據庫是:
建立數據的語法以下:
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS]database_name[COMMENT 'database_comment']
[LOCATION hdfs_path];
數據庫實際對應 HDFS 中 Impala 數據目錄中的目錄,目錄名爲數據庫名+.db。假如 HDFS 中相關目錄不存在則自動建立。全部數據庫和它們相關的目錄是頂層對象,沒有邏輯或物理嵌套(All databases and their associated directories are top-level objects, with no physical or logical nesting)。
使用注意:
當建立數據庫以後,在 impala-shell 會話中,使用 USE 語句切換爲當前數據庫。你能夠不加數據庫名前綴訪問當前數據庫中的表。
當第一次使用 impala-shell 鏈接到 Impala,默認的開始數據庫是 (在執行任意的 CREATE DATABASE 或 USE 語句前) default。
當建立數據庫以後,你的 impala-shell 會話或其餘的鏈接到相同節點的 impala-shell 會話能夠當即訪問該數據庫。當經過其餘節點的 Impala 守護進程訪問該數據庫時,應先執行 INVALIDATE METADATA 語句
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
例子:
create database first;
use first;
create table t1 (x int);
create database second;
use second;
-- 數據庫中的表以數據庫名做爲它的命名空間
-- 不一樣的數據庫中能夠有同名的表
create table t1 (s string);
create database temp;
-- 建立數據庫後沒有使用 USE 語句切換數據庫,而是經過數據庫名前綴來標識表
create table temp.t2 (x int, y int);
use database temp;
create table t3 (s string);
-- 當數據庫被 USE 語句選中時,沒法刪除
drop database temp; ERROR: AnalysisException: Cannot drop current default database: temp -- The always-available database 'default' is a convenient one to USE.
use default;
-- 刪除數據庫能夠快速刪除下面的全部表
drop database temp;
語句類型: DDL
CREATE FUNCTION 語句
建立一個用戶定義函數(UDF),當執行 SELECT 或 INSERT 操做時,能夠實現自定義的邏輯。
語法:
建立標量函數(scalar UDF)與聚合函數(UDA)的語法不一樣。標量函數每行調用一次,執行單個函數(which is called once for each row and implemented by a single function),而用戶定義聚合函數執行多個函數跨越多組行的中間結果(which is implemented by multiple functions that compute intermediate results across sets of rows)。
執行 CREATE FUNCTION 語句建立標量函數:
CREATE FUNCTION [IF NOT EXISTS] [db_name.]function_name([arg_type[,arg_type...])
RETURNS return_type LOCATION 'hdfs_path'
SYMBOL='symbol_or_class'
執行 CREATE AGGREGATE FUNCTION 語句建立 UDA:
CREATE [AGGREGATE] FUNCTION [IF NOT EXISTS] [db_name.]function_name([arg_type[,arg_type...])
RETURNSreturn_typeLOCATION 'hdfs_path'
[INIT_FN='function]
UPDATE_FN='function MERGE_FN='function [FINALIZE_FN='function]
標量與聚合函數:
最簡單的一種用戶定義函數每次調用時返回一個標量值,典型的是結果集中每一行返回一個值。這種普通的函數一般稱爲 UDF。用戶定義聚合函數(UDA) 是一種特別的基於多行的內容產生單一值的 UDF。一般 UDA 會與 GROUP BY子句聯合使用,壓縮大的結果集到一個小的結果集,甚至對整表產生一個概述列(This general kind of function is what is usually meant by UDF. User-defined aggregate functions (UDAs) are a specialized kind of UDF that produce a single value based on the contents of multiple rows. You usually use UDAs in combination with a GROUP BY clause to condense a large result set into a smaller one, or even a single row summarizing column values across an entire table)。
使用 CREATE AGGREGATE FUNCTION 語句建立 UDA。 僅當建立 UDA 而不是 標量 UDF 時,INIT_FN, UPDATE_FN, MERGE_FN, FINALIZE_FN, INTERMEDIATE 子句被使用。
使用 *_FN 子句指定的函數在函數處理的不一樣階段進行調用。
假如你對每個相關的函數使用一致的命名約定,Impala 基於最初的子句能夠自動的肯定函數名稱,所以其他的是可選的(If you use a consistent naming convention for each of the underlying functions, Impala can automatically determine the names based on the first such clause, so the others are optional)。
關於 UAD 的點對點(end-to-end)的例子,參見 User-Defined Functions for Impala.
使用注意:
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
語句類型: DDL
兼容性:
Impala 能夠運行 Hive 中建立的 UDF,只要它使用 Impala-compatible 數據類型 (沒有組合或嵌套列類型)。Hive 能夠運行 Impala 中建立的基於 JAVA(Java-based)的 UDF,而不能使用 C++編寫的 UDF。
更多信息: 參見 User-Defined Functions for Impala 瞭解更多 Impala 中 UDF 的背景信息,使用介紹和例子。
CREATE TABLE 語句
建立表並指定它的列的語法以下:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name[(col_namedata_type[COMMENT 'col_comment'], ...)]
[COMMENT 'table_comment']
[PARTITIONED BY (col_namedata_type[COMMENT 'col_comment'], ...)]
[
[ROW FORMATrow_format] [STORED ASfile_format]
]
[LOCATION 'hdfs_path']
[WITH SERDEPROPERTIES ('key1'='value1', 'key2'='value2', ...)]
[TBLPROPERTIES ('key1'='value1', 'key2'='value2', ...)]
data_type
:primitive_typeprimitive_type
: TINYINT
| SMALLINT
| INT
| BIGINT
| BOOLEAN
| FLOAT
| DOUBLE
| STRING
| TIMESTAMP
row_format
: DELIMITED [FIELDS TERMINATED BY 'char' [ESCAPED BY 'char']]
[LINES TERMINATED BY 'char']
file_format:
PARQUET | PARQUETFILE
| TEXTFILE
| SEQUENCEFILE
| RCFILE
內部表和外部表:
Impala 默認建立 "內部" 表--由 Impala 管理表相關的數據文件,當表刪除時同時實際刪除數據文件。假如使用了 EXTERNAL 子句,Impala 將建立 "外部" 表--一般由 Impala 外部產生數據文件,並從它們原來的 HDFS 中的位置進行查詢,當刪除表時 Impala 不處理這些數據文件
分區表:
PARTITIONED BY 子句根據一個或多個指定列的值拆分數據文件。Impala 查詢可使用分區元數據來最小化讀取和網絡之間傳遞的數據,特別是鏈接查詢時。更多信息參見 Partitioning.
指定文件格式:
STORED AS 子句標識了相關數據文件的格式。目前 Impala 能夠查詢超出其能夠建立與插入數據的文件格式。對於 Impala 當前不支持的格式,在 Hive 中執行建立或數據載入操做。例如,Impala 能夠建立 SequenceFile 表可是沒法載入數據。這也是 Impala 處理各類壓縮文件的特定格式(There are also Impala-specific procedures for using compression with each kind of file format)。關於與不一樣數據文件格式協做的詳細信息,參見 How Impala Works with Hadoop File Formats。
默認(不使用 STORED AS 子句時)的,Impala 中表建立的數據文件是以 Ctrl-A 做爲分隔符的文本文件。使用 ROW FORMAT 子句指定使用不一樣的分隔符生成或從文件提取數據,如 tab 或 |,或指定不一樣的行結束符,如回車或換行。當指定分隔符和行結束符號時,用 '\t' 表示 tab,'\n' 表示回車, '\r' 表示換行。
ESCAPED BY 子句對經過 INSERT 語句插入到 Impala TEXTFILE 表的數據文件和已有的直接放置到 Impala 表目錄中的文件都有效(你可使用如下方式提取已有文件的數據:使用 CREATE EXTERNAL TABLE ... LOCATION 語句, 使用 LOAD DATA 語句, 或經過 HDFS 操做如 hdfs dfs -put file hdfs_path)。選擇一種不會在文件中其餘部分使用的字符做爲轉義字符,當字段值中出現分隔符時放在每一個分隔符實例以前(Choose an escape character that is not used anywhere else in the file, and put it in front of each instance of the delimiter character that occurs within a field value)。被引號引發的字段表示 Impala 不須要對包含嵌入的分隔符的進行解析(Surrounding field values with quotation marks does not help Impala to parse fields with embedded delimiter characters);引號標誌它是組成整個列值的一部分。以下想用 \ 做爲轉義符,須要在 impala-shell 中使用 ESCAPED BY '\\' 進行指定。
克隆表:
使用如下語句,建立一個與其餘表具備相同的列、備註、以及其餘屬性的空表。CREATE TABLE ... LIKE 語句包含一組子句集,當前只支持 LOCATION, COMMENT, STORED AS 子句:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
LIKE [db_name.]table_name
[COMMENT 'table_comment']
[STORED ASfile_format]
[LOCATION 'hdfs_path']
Note: 但願在一個操做中同時克隆表結構和數據,則使用下面介紹的 CREATE TABLE AS SELECT 語句。
當使用 CREATE TABLE ... LIKE 語句克隆現有表的結構時,新表與原表使用相同的文件格式,所以假如你想要使用不一樣的文件格式時使用 STORED AS 子句指定新的文件格式。
一般 Impala 不能直接建立 HBase 表,但 Impala 可使用 CREATE TABLE ... LIKE 語句克隆 HBase 表,保留原始表的文件格式和元數據。
使用 CREATE TABLE ... LIKE 語句克隆 Avro 表時可能有一些例外狀況。例如沒法用此技術克隆一個設置了 Avro schema 可是沒有列的 Avro 表。當有疑問時,在 Hive 中測試運行 CREATE TABLE ... LIKE 操做;若是也有問題,那麼他一般在 Impala 中也不會正常。
若是原始表是分區表,新表會繼承相同的分區鍵列。由於新表初始化爲空表,它沒有繼承原始表的實際分區。使用插入數據或執行 ALTER TABLE ... ADD PARTITION 語句在新表上建立分區。
由於 CREATE TABLE ... LIKE 只是操做了表的元數據而不是表的物理數據,能夠在以後執行 INSERT INTO TABLE 語句從原始表複製一些數據到新表,也能夠同時轉換爲新的文件格式(對於一些文件格式,Impala 能夠經過 CREATE TABLE ... LIKE 進行建立,可是不能插入這些文件格式的數據;這時候就必須使用 Hive 加載數據。參考 How Impala Works with Hadoop File Formats 瞭解詳細信息)。
CREATE TABLE AS SELECT:
CREATE TABLE AS SELECT 語法同時完成建立基於原始表所定義的列的新表,從原始表複製數據到新表,並且不須要單獨執行 INSERT 語句。這一語句如此流行,都有本身的縮寫 "CTAS"。CREATE TABLE AS SELECT 語法以下:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS]db_name.]table_name
[COMMENT 'table_comment']
[STORED ASfile_format]
[LOCATION 'hdfs_path']
AS
select_statement
參考 SELECT Statement 瞭解關於 CTAS 語句中 SELECT 位置的語法信息。
新建立的表繼承了從原始表中選出的列名,也能夠經過在查詢中指定列別名來修改。列和表的註釋都不會從原始表中繼承。
下面例子演示瞭如何克隆原始表全部數據、列和/或行的部分子集,重排列的順序,重命名列,用表達式構建新列等:
-- 建立新表並複製全部數據
CREATE TABLE clone_of_t1 AS SELECT * FROM t1;
-- 與 CREATE TABLE LIKE 功能相同
CREATE TABLE empty_clone_of_t1 AS SELECT * FROM t1 WHERE 1=0;
-- 複製部分數據
CREATE TABLE subset_of_t1 AS SELECT * FROM t1 WHERE x > 100 AND y LIKE 'A%';
CREATE TABLE summary_of_t1 AS SELECT c1, sum(c2) AS total, avg(c2) AS average FROM t1 GROUP BY c2;
-- 修改文件格式
CREATE TABLE parquet_version_of_t1 AS SELECT * FROM t1 STORED AS PARQUET;
-- 建立與原始表不一樣列順序、列名和數據類型的表
CREATE TABLE some_columns_from_t1 AS SELECT c1, c3, c5 FROM t1;
CREATE TABLE reordered_columns_from_t1 AS SELECT c4, c3, c1, c2 FROM t1;
CREATE TABLE synthesized_columns AS SELECT upper(c1) AS all_caps, c2+c3 AS total, "California" AS state FROM t1;
做爲 CTAS 操做的一部分,你能夠採用任意 Impala 可寫的數據文件格式(當前支持 TEXTFILE 和 PARQUET).。但不能設置文本文件表的底層屬性(lower-level properties)如分隔符。儘管可使用分區表做爲源表並從中複製數據,可是不能設置新表的分區子句。
Visibility and Metadata:
你能夠經過 TBLPROPERTIES 子句關聯任意對象到表的元數據。這會產生一組逗號分隔的鍵值對並保存到 metastore 數據庫中。建立以後可使用 ALTER TABLE 語句來修改這些屬性。當前 Impala 查詢不使用表屬性字段裏的這些數據。一些與其餘 Hadoop 組件的交互須要設置 TBLPROPERTIES 字段爲特定的值,例如建立 Avro 表或 HBase 表(一般在 Hive 中建立這些特定類型的表,由於這些表須要一些當前 Impala 不支持的額外子句)。
你也能夠經過 WITH SERDEPROPERTIES 子句指定鍵值對來關聯表的 SerDes 屬性。Impala 有本身的內置的所支持文件的序列化和反序列化器,所以不使用這個屬性。爲了與 Hive 兼容,一些文件格式的轉換須要特定的屬性值。
執行 DESCRIBE table_name 語句查看錶的列定義和列備註,例如在執行 CREATE TABLE ... LIKE 或 CREATE TABLE ... AS SELECT 語句以前。使用 DESCRIBE FORMATTED table_name 語句來查看更詳細的信息,如數據文件的位置和如 ROW FORMAT 和 STORED AS 等子句的值。要查看總體表的註釋(而不是單獨列的註釋)也須要使用 DESCRIBE FORMATTED 語句。
當建立了表以後,當前 impala-shell 會話與其餘鏈接到相同節點的 impala-shell 會話能夠馬上看到這個表。當鏈接到其餘節點,經過 Impala 守護進程查詢這個表以前,應先執行 INVALIDATE METADATA 語句。
Hive considerations:
Impala 查詢會使用表和列的元數據,如表的行數或列的不一樣值個數。在 Impala 1.2.2 以前,當建立完表和載入相應的數據後,須要在 Hive 中執行 ANALYZE TABLE 語句來收集這些元數據信息。在 Impala 1.2.2 及以上版本,Impala 中 COMPUTE STATS 語句能夠生成這些統計信息,再也不須要在 Hive 中運行。
Note:
Impala 的 CREATE TABLE 語句不能建立 HBase 表,由於當前不支持 HBase 表所需的 STORED BY 子句。能夠在 Hive 中建立表,在 Impala 中查詢。關於 Impala 使用 HBase 表的信息,參考 Using Impala to Query HBase Tables。
CREATE VIEW 語句
CREATE VIEW 語句爲複雜的查詢建立一個簡寫。所基於的查詢能夠執行鏈接、表達式、重排序列、列別名和其餘的 SQL 功能,能夠是一個難於理解和維護的查詢。
由於視圖是個純粹的邏輯結構(查詢的別名)沒有對應實體的數據,因此 ALTER VIEW 只會修改 metastore 數據庫中的元數據,而不會涉及 HDFS 中的任意數據文件。
CREATE VIEW view_name[(column_list)]
AS select_statement
CREATE VIEW 語句可用以一下場景:
原始查詢越複雜越難以閱讀,使用視圖的簡單查詢越有效果。
對於須要一遍遍重複的查詢的複雜子句,例如在查詢項, ORDER BY, GROUP BY 子句,你可使用 WITH 子句做爲建立視圖的替代方案(you can use the WITH clause as an alternative to creating a view)。
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
例子:
create view v1 as select * from t1;
create view v2 as select c1, c3, c7 from t1;
create view v3 as select c1, cast(c3 as string) c3, concat(c4,c5) c5, trim(c6) c6, "Constant" c8 from t1;
create view v4 as select t1.c1, t2.c2 from t1 join t2 on (t1.id=t2.id);
create view some_db.v5 as select * from some_other_db.t1;
Statement type: DDL
DESCRIBE 語句
DESCRIBE 語句顯示錶的元數據,例如列的名稱和數據類型。語法爲:
DESCRIBE [FORMATTED] table
也可使用簡寫 DESC。
DESCRIBE FORMATTED 顯示更多信息,顯示格式與 Apache Hive 相似。擴展信息包括底層詳細信息如表是內部表仍是外部表,什麼時候建立,文件格式,HDFS 中數據文件位置,對象是表仍是視圖,以及(對視圖來講)從視圖定義中得到的查詢語句。
Note: Compressed 字段表是否包含壓縮數據的可靠標誌。一般老是 No,由於僅當會話載入數據的時候使用壓縮設置,並不會持久保存到表的元數據中。
Usage notes:
當 impalad 守護進程重啓後,對某個表的第一次查詢可能會比以後的查詢時間長,由於該查詢執行時會把表的元數據載入到內存中。這種對每一個表的一次性(one-time)的延遲可能會誤導基準測試的結果或形成沒必要要的擔心。能夠爲每個要查詢的表執行 DESCRIBE 語句,爲 Impala 的元數據緩存"熱身"("warm up")。
當處理保存在 HDFS 中的數據文件時,有時候瞭解諸如 Impala 表對應的數據文件的路徑、namenode 的主機名此類的信息很重要。你能夠經過 DESCRIBE FORMATTED 的輸出獲取這些信息。在諸如 LOAD DATA 和 CREATE TABLE / ALTER TABLE 中的 LOCATION 子句須要指定 HDFS URIs 或路徑。在 Linux 命令如 hadoop 和 hdfs 對 HDFS 中的數據文件執行復制,重命名等操做時,也須要知道 HDFS URIs 或路徑。
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
每一個表都包括對應的表統計信息和列統計信息。使用 SHOW TABLE STATS table_name 和 SHOW COLUMN STATS table_name 語句來查看這些分類的信息。參見 SHOW Statement 瞭解詳細信息。
Important: 對於性能關鍵( performance-critical)查詢中用到的表,插入或替換數據以後,應執行 COMPUTE STATS 語句以確保全部統計信息是最新的。 在 Impala 中執行了 INSERT, LOAD DATA, CREATE TABLE AS SELECT 語句以後,或者在 Hive 中加載數據並在 Impala 中執行 REFRESH table_name以後, 應考慮更新表的統計信息。對於包含大量數據的表、用於鏈接查詢的表,這一技術特別重要。
例子:
下面的例子演示了對不一樣模式對象使用標準 DESCRIBE 和 DESCRIBE FORMATTED 的結果:
[localhost:21000] > create table t1 (x int, y int, s string);
Query: create table t1 (x int, y int, s string)
[localhost:21000] > describe t1;
Query: describe t1
Query finished, fetching results ...
+------+--------+---------+
| name | type | comment |
+------+--------+---------+
| x | int | |
| y | int | |
| s | string | |
+------+--------+---------+
Returned 3 row(s) in 0.13s
[localhost:21000] > describe formatted t1;
Query: describe formatted t1
Query finished, fetching results ...
+------------------------------+--------------------------------------------------------------------+----------------------+
| name | type | comment |
+------------------------------+--------------------------------------------------------------------+----------------------+
| # col_name | data_type | comment |
| | NULL | NULL |
| x | int | None |
| y | int | None |
| s | string | None |
| | NULL | NULL |
| # Detailed Table Information | NULL | NULL |
| Database: | describe_formatted | NULL |
| Owner: | cloudera | NULL |
| CreateTime: | Mon Jul 22 17:03:16 EDT 2013 | NULL |
| LastAccessTime: | UNKNOWN | NULL |
| Protect Mode: | None | NULL |
| Retention: | 0 | NULL |
| Location: | hdfs://127.0.0.1:8020/user/hive/warehouse/describe_formatted.db/t1 | NULL |
| Table Type: | MANAGED_TABLE | NULL |
| Table Parameters: | NULL | NULL |
| | transient_lastDdlTime | 1374526996 |
| | NULL | NULL |
| # Storage Information | NULL | NULL |
| SerDe Library: | org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe | NULL |
| InputFormat: | org.apache.hadoop.mapred.TextInputFormat | NULL |
| OutputFormat: | org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat | NULL |
| Compressed: | No | NULL |
| Num Buckets: | 0 | NULL |
| Bucket Columns: | [] | NULL |
| Sort Columns: | [] | NULL |
+------------------------------+--------------------------------------------------------------------+----------------------+
Returned 26 row(s) in 0.03s
[localhost:21000] > create view v1 as select x, upper(s) from t1;
Query: create view v1 as select x, upper(s) from t1
[localhost:21000] > describe v1;
Query: describe v1
Query finished, fetching results ...
+------+--------+---------+
| name | type | comment |
+------+--------+---------+
| x | int | |
| _c1 | string | |
+------+--------+---------+
Returned 2 row(s) in 0.10s
[localhost:21000] > describe formatted v1;
Query: describe formatted v1
Query finished, fetching results ...
+------------------------------+------------------------------+----------------------+
| name | type | comment |
+------------------------------+------------------------------+----------------------+
| # col_name | data_type | comment |
| | NULL | NULL |
| x | int | None |
| _c1 | string | None |
| | NULL | NULL |
| # Detailed Table Information | NULL | NULL |
| Database: | describe_formatted | NULL |
| Owner: | cloudera | NULL |
| CreateTime: | Mon Jul 22 16:56:38 EDT 2013 | NULL |
| LastAccessTime: | UNKNOWN | NULL |
| Protect Mode: | None | NULL |
| Retention: | 0 | NULL |
| Table Type: | VIRTUAL_VIEW | NULL |
| Table Parameters: | NULL | NULL |
| | transient_lastDdlTime | 1374526598 |
| | NULL | NULL |
| # Storage Information | NULL | NULL |
| SerDe Library: | null | NULL |
| InputFormat: | null | NULL |
| OutputFormat: | null | NULL |
| Compressed: | No | NULL |
| Num Buckets: | 0 | NULL |
| Bucket Columns: | [] | NULL |
| Sort Columns: | [] | NULL |
| | NULL | NULL |
| # View Information | NULL | NULL |
| View Original Text: | SELECT x, upper(s) FROM t1 | NULL |
| View Expanded Text: | SELECT x, upper(s) FROM t1 | NULL |
+------------------------------+------------------------------+----------------------+
Returned 28 row(s) in 0.03s
[localhost:21000] > create external table t2 (x int, y int, s string) stored as parquet location '/user/cloudera/sample_data';
[localhost:21000] > describe formatted t2;
Query: describe formatted t2
Query finished, fetching results ...
+------------------------------+----------------------------------------------------+----------------------+
| name | type | comment |
+------------------------------+----------------------------------------------------+----------------------+
| # col_name | data_type | comment |
| | NULL | NULL |
| x | int | None |
| y | int | None |
| s | string | None |
| | NULL | NULL |
| # Detailed Table Information | NULL | NULL |
| Database: | describe_formatted | NULL |
| Owner: | cloudera | NULL |
| CreateTime: | Mon Jul 22 17:01:47 EDT 2013 | NULL |
| LastAccessTime: | UNKNOWN | NULL |
| Protect Mode: | None | NULL |
| Retention: | 0 | NULL |
| Location: | hdfs://127.0.0.1:8020/user/cloudera/sample_data | NULL |
| Table Type: | EXTERNAL_TABLE | NULL |
| Table Parameters: | NULL | NULL |
| | EXTERNAL | TRUE |
| | transient_lastDdlTime | 1374526907 |
| | NULL | NULL |
| # Storage Information | NULL | NULL |
| SerDe Library: | org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe | NULL |
| InputFormat: | com.cloudera.impala.hive.serde.ParquetInputFormat | NULL |
| OutputFormat: | com.cloudera.impala.hive.serde.ParquetOutputFormat | NULL |
| Compressed: | No | NULL |
| Num Buckets: | 0 | NULL |
| Bucket Columns: | [] | NULL |
| Sort Columns: | [] | NULL |
+------------------------------+----------------------------------------------------+----------------------+
Returned 27 row(s) in 0.17s
Statement type: DDL
DISTINCT 操做符
SELECT 語句中的 DISTINCT 操做符用於過濾結果結果集中的重複值:
-- 返回一個列的惟一值列表
-- 如何有值爲 NULL 的行,則 NULL 也做爲返回值之一顯示
select distinct c_birth_country from customer;
-- 返回多個列值的惟一組合
select distinct c_salutation, c_last_name from customer;
能夠組合使用 DISTINCT 和聚合函數,一般是 COUNT(),來查找一個列有多少不一樣的值:
-- 統計列的惟一值個數
-- 在 count 時 NULL 值不計入惟一值中
select count(distinct c_birth_country) from customer;
-- 計算惟一值組合的個數
select count(distinct c_salutation, c_last_name) from customer;
Impala SQL 不支持的一個結構是在同一個查詢中使用多個聚合函數時使用 DISTINCT 。例如,你沒法在一個查詢列表中中同時計算 COUNT(DISTINCT c_first_name) 和 COUNT(DISTINCT c_last_name)
Note:
在一些數據庫系統中總會返回排序後的 DISTINCT 值,Impala 不會對 DISTINCT 值進行排序。假如你須要按字母或數字排序值,必須使用 ORDER BY 子句
DOUBLE 數據類型
8字節(雙精度)浮點數據類型,用於 CREATE TABLE 和 ALTER TABLE 語句。
Range: 4.94065645841246544e-324d .. 1.79769313486231570e+308, 正或負
Conversions: Impala 不支持 DOUBLE 到其餘數據類型的自動轉換。可使用 CAST() 轉換 DOUBLE 值爲 FLOAT, TINYINT, SMALLINT, INT, BIGINT, STRING, TIMESTAMP, BOOLEAN。可使用指數表示法表示 DOUBLE,也能夠從字符串轉換爲 DOUBLE 時使用,例如,1.0e6 表示1百萬。
數據類型 REAL 是 DOUBLE 的別名
Related information: Mathematical Functions
DROP DATABASE 語句
從系統中刪除數據庫,同時刪除 HDFS 中對應的 *.db 目錄。爲了不丟失數據,刪除數據庫以前數據庫必須爲空。
刪除數據庫的語法是:
DROP (DATABASE|SCHEMA) [IF EXISTS] database_name;
在刪除數據庫以前,先使用 DROP TABLE, DROP VIEW, ALTER TABLE, ALTER VIEW 語句,刪除全部的表和視圖,或者把它們移動到其餘數據庫。
例子:
參見 CREATE DATABASE Statement 中包含 CREATE DATABASE, USE, DROP DATABASE 語句的例子
DROP FUNCTION 語句
移除用戶定義函數(UDF),而後在 Impala SELECT 或 INSERT 操做者該函數再也不可用
語法:
DROP [AGGREGATE] FUNCTION [IF EXISTS] [db_name.]function_name
Statement type: DML (但受 SYNC_DDL 查詢選項影響)
DROP TABLE 語句
刪除表語法爲:
DROP TABLE [IF EXISTS] [db_name.]table_name
默認 Impala 會同時刪除該表對應的 HDFS 目錄和數據文件。假如執行了 DROP TABLE 語句而數據問題沒有刪除,多是如下緣由:
請使用 USE 語句選擇數據庫或使用完整的標識名 db_name.table_name,以確保刪除正確的數據庫下的表。
使用可選的 IF EXISTS 子句以後,不管表是否存在語句都會執行成功。若是表存在,將對其進行刪除操做;若是表不存在,語句則不起做用。這一能力對於刪除現有模式對象並建立新對象的標準化安裝腳本有意義。經過組合使用包含 IF EXISTS 的 DROP 語句包含 IF NOT EXISTS 子句的 CREATE 語句,腳本能夠第一次時(當對象還不存在時) 和以後都容許成功(當其中一些對象已經存在時)。
假如想對數據庫執行 DROP DATABASE 語句,首先應當對數據庫中的全部表執行 DROP TABLE 語句刪除這些表。
例子:
create database temporary;
use temporary;
create table unimportant (x int);
create table trivial (s string);
-- 刪除當前數據庫中的表
drop table unimportant;
-- 切換到其它數據庫
use default;
-- 刪除 default 數據庫中的表
drop table trivial; ERROR: AnalysisException: Table does not exist: default.trivial -- ...use a fully qualified name.
drop table temporary.trivial;
Statement type: DML (但仍受 SYNC_DDL 查詢選項影響)
DROP VIEW 語句
移除原來由 CREATE VIEW 語句建立的指定的視圖。由於視圖是純邏輯結構 (是查詢的別名)沒有對應的數據,DROP VIEW 只會修改 metastore 數據庫中的元數據,不會影響 HDFS 中的數據文件。
DROP VIEW [database_name.]view_name
Statement type: DML (但仍受 SYNC_DDL 查詢選項影響)
EXPLAIN 語句
返回語句的執行計劃,顯示 Impala 將用來讀取數據,在集羣節點中劃分工做,在網絡間傳輸中間數據和最終結果的底層機制。在 EXPLAIN 語句後面跟着完整的 SQL 語句,例如:
[impalad-host:21000] > explain select count(*) from customer_address;
PLAN FRAGMENT 0
PARTITION: UNPARTITIONED
3:AGGREGATE
| output: SUM(<slot 0>)
| group by:
| tuple ids: 1
|
2:EXCHANGE
tuple ids: 1
PLAN FRAGMENT 1
PARTITION: RANDOM
STREAM DATA SINK
EXCHANGE ID: 2
UNPARTITIONED
1:AGGREGATE
| output: COUNT(*)
| group by:
| tuple ids: 1
|
0:SCAN HDFS
table=default.customer_address #partitions=1 size=5.25MB
tuple ids: 0
你能夠查看輸出結果以判斷查詢是否高效執行,若是沒有則調整語句和/或模式(You can interpret the output to judge whether the query is performing efficiently, and adjust the query and/or the schema if not)。例如,你能夠修改 WHERE 子句,添加提示以更有效地執行鏈接操做,引入子查詢,修改錶鏈接的順序,添加或修改表的分區,在 Hive 中收集列和/或表的統計信息,或其餘的性能調整步驟以進行測試(For example, you might change the tests in the WHERE clause, add hints to make join operations more efficient, introduce subqueries, change the order of tables in a join, add or change partitioning for a table, collect column statistics and/or table statistics in Hive, or any other performance tuning steps)。
若是你是傳統數據庫背景對數據倉庫不熟悉,請記住 Impala 是針對很是大的表的全表掃描進行的優化。數據結構和分佈一般不適於一般的 OLTP 環境下的各類索引和單行查找(The structure and distribution of this data is typically not suitable for the kind of indexing and single-row lookups that are common in OLTP environments)。見到掃描整個大表的查詢是很尋常的,並不必定是低效查詢的標識(Seeing a query scan entirely through a large table is quite common, not necessarily an indication of an inefficient query)。固然,你能夠減小掃描數據的數量級,例如經過使用只對分區表特定分區查找的查詢,能夠提升速度的幾個數量級,yibiantazaijimiaozhyunx. Of course, if you can reduce the volume of scanned data by orders of magnitude, for example by using a query that affects only certain partitions within a partitioned table, then you might speed up a query so that it executes in seconds rather than minutes or hours.
更多信息和例子,以幫助你理解 EXPLAIN 輸出,請參考 Understanding the EXPLAIN Plan。
擴展 EXPLAIN 輸出:
爲了性能調整和容量規劃(例如在 CDH 5 使用資源管理功能),你能夠啓用 EXPLAIN 語句更詳細的信息輸出。在 impala-shell 中執行 SET EXPLAIN_LEVEL=verbose 命令。要恢復到原來簡潔的 EXPLAIN 輸出,執行 SET EXPLAIN_LEVEL=normal 命令(你也可使用 1 或 0 做爲參數傳遞個 SET 命令以啓用或禁用擴展輸出)
當啓用擴展 EXPLAIN 輸出後,EXPLAIN 語句打印關於預估的內存需求, 虛擬核心的最小數量(minimum number of virtual cores), 以及其餘可用於微調資源管理的選項,參見 impalad Startup Options for Resource Management 中的描述。(當你設置了 MEM_LIMIT 選項估計了內存數量,預估的內存需求應當略有偏高的,留有犯錯的餘地,以免沒必要要的取消查詢)。
擴展 EXPLAIN 輸出也報告查詢中調用的表的表和列的統計信息是否可用。參見 Table Statistics 和 Column Statistics 瞭解不一樣種類的統計信息幫助 Impala 優化查詢的細節。
[localhost:21000] > set explain_level=verbose;
EXPLAIN_LEVEL set to verbose
[localhost:21000] > explain select x from t1;
Query: explain select x from t1
+----------------------------------------------------------+
| Explain String |
+----------------------------------------------------------+
| Estimated Per-Host Requirements: Memory=64.00MB VCores=1 |
| |
| PLAN FRAGMENT 0 |
| PARTITION: UNPARTITIONED |
| |
| 1:EXCHANGE |
| cardinality: unavailable |
| per-host memory: unavailable |
| tuple ids: 0 |
| |
| PLAN FRAGMENT 1 |
| PARTITION: RANDOM |
| |
| STREAM DATA SINK |
| EXCHANGE ID: 1 |
| UNPARTITIONED |
| |
| 0:SCAN HDFS |
| table=default.t1 #partitions=1/1 size=18B |
| table stats: unavailable |
| column stats: unavailable |
| cardinality: unavailable |
| per-host memory: 64.00MB |
| tuple ids: 0 |
+----------------------------------------------------------+
Returned 24 row(s) in 0.01s
切換到 Hive shell 收集表和列的統計信息:
hive> analyze table t1 compute statistics;
hive> analyze table t1 compute statistics for columns x;
返回 impala-shell 確認統計信息被 Impala 查詢承認。應先執行 REFRESH table 語句,以便載入新的元數據。
[localhost:21000] > set explain_level=verbose;
EXPLAIN_LEVEL set to verbose
[localhost:21000] > refresh t1;
[localhost:21000] > explain select x from t1;
+----------------------------------------------------------+
| Explain String |
+----------------------------------------------------------+
| Estimated Per-Host Requirements: Memory=64.00MB VCores=1 |
| |
| PLAN FRAGMENT 0 |
| PARTITION: UNPARTITIONED |
| |
| 1:EXCHANGE |
| cardinality: unavailable |
| per-host memory: unavailable |
| tuple ids: 0 |
| |
| PLAN FRAGMENT 1 |
| PARTITION: RANDOM |
| |
| STREAM DATA SINK |
| EXCHANGE ID: 1 |
| UNPARTITIONED |
| |
| 0:SCAN HDFS |
| table=default.t1 #partitions=1/1 size=18B |
| table stats: 0 rows total |
| column stats: all |
| cardinality: unavailable |
| per-host memory: 64.00MB |
| tuple ids: 0 |
+----------------------------------------------------------+
Returned 24 row(s) in 0.02s
External Tables
CREATE EXTERNAL TABLE 語句設置 Impala 表指向一個現存的可能在正常的 Impala 數據文件目錄之外的 HDFS 位置的數據文件。當你已經在已知的 HDFS 位置有數據文件,這一操做完成以指望的文件格式導入數據到新表裏面(This operation saves the expense of importing the data into a new table when you already have the data files in a known location in HDFS, in the desired file format)。
FLOAT 數據類型
4字節(單精度)浮點數據類型,用於 CREATE TABLE 和 ALTER TABLE 語句。
Range: 1.40129846432481707e-45 .. 3.40282346638528860e+38, 正或負
Conversions: Impala 自動轉換 FLOAT 爲更大精度的 DOUBLE , but not the other way around. 可使用 CAST() 轉換 FLOAT 值爲 FLOAT, TINYINT, SMALLINT, INT, BIGINT, STRING, TIMESTAMP, BOOLEAN。可使用指數表示法表示 FLOAT,也能夠從字符串轉換爲 FLOAT 時使用,例如,1.0e6 表示1百萬。
Related information: Mathematical Functions
GROUP BY 子句
在使用相似 COUNT(), SUM(), AVG(), MIN(), MAX() 等聚合函數的查詢中使用 GROUP BY 子句。在 GROUP BY 子句中列出全部不參與聚合操做的列。
例如, 下面的查詢查找總銷售量最高的前 5 個項目(使用 SUM() 函數計算銷售量,並統計銷售交易的數量(使用 COUNT() 函數)。由於項目對應的 ID 列不用於聚合函數,在 GROUP BY 子句指定此列:
select ss_item_sk as Item, count(ss_item_sk) as Times_Purchased, sum(ss_quantity) as Total_Quantity_Purchased
from store_sales group by ss_item_sk order by sum(ss_quantity) desc
limit 5;
+-------+-----------------+--------------------------+
| item | times_purchased | total_quantity_purchased |
+-------+-----------------+--------------------------+
| 9325 | 372 | 19072 |
| 4279 | 357 | 18501 |
| 7507 | 371 | 18475 |
| 5953 | 369 | 18451 |
| 16753 | 375 | 18446 |
+-------+-----------------+--------------------------+
使用 HAVING 子句用於過濾聚合函數的結果,由於不能在 WHERE 子句中使用那些表達式的值。好比,查找 5 個 100 以上銷售交易的最低銷售量物品可使用如下查詢:
select ss_item_sk as Item, count(ss_item_sk) as Times_Purchased, sum(ss_quantity) as Total_Quantity_Purchased
from store_sales group by ss_item_sk having times_purchased >= 100 order by sum(ss_quantity)
limit 5;
+-------+-----------------+--------------------------+
| item | times_purchased | total_quantity_purchased |
+-------+-----------------+--------------------------+
| 13943 | 105 | 4087 |
| 2992 | 101 | 4176 |
| 4773 | 107 | 4204 |
| 14350 | 103 | 4260 |
| 11956 | 102 | 4275 |
+-------+-----------------+--------------------------+
當執行涉及到科學或財務數據計算時,記住 FLOAT 或 DOUBLE 做爲真正的、不能精確表示每個分數值的浮點數存儲(When performing calculations involving scientific or financial data, remember that columns with type FLOAT or DOUBLE are stored as true floating-point numbers, which cannot precisely represent every possible fractional value)。所以,如何你的 GROUP BY 子句包含 FLOAT 或 DOUBLE 列,查詢結果可能不會精確匹配查詢中的字面值或原始文本件(the results might not precisely match literal values in your query or from an original Text data file)。使用舍入操做、BETWEEN 操做符、或其餘運算技術以匹配最「接近」你指望浮點數的字面值。例如,在 ss_wholesale_cost 列上的查詢返回的成本值接近但不徹底等於被輸入的原始分數值。
select ss_wholesale_cost, avg(ss_quantity * ss_sales_price) as avg_revenue_per_sale
from sales
group by ss_wholesale_cost
order by avg_revenue_per_sale desc
limit 5;
+-------------------+----------------------+
| ss_wholesale_cost | avg_revenue_per_sale |
+-------------------+----------------------+
| 96.94000244140625 | 4454.351539300434 |
| 95.93000030517578 | 4423.119941283189 |
| 98.37999725341797 | 4332.516490316291 |
| 97.97000122070312 | 4330.480601655014 |
| 98.52999877929688 | 4291.316953108634 |
+-------------------+----------------------+
Notice how wholesale cost values originally entered as decimal fractions such as 96.94 and 98.38 are slightly larger or smaller in the result set, due to precision limitations in the hardware floating-point types. The imprecise representation of FLOAT and DOUBLE values is why financial data processing systems often store currency using data types that are less space-efficient but avoid these types of rounding errors.
HAVING 子句
經過檢測聚合函數的結果而不是檢測表中的每一行來對 SELECT 查詢的結果進行過濾(Performs a filter operation on a SELECT query, by examining the results of aggregation functions rather than testing each individual table row)。所以老是與聚合函數如 COUNT(), SUM(), AVG(), MIN(), MAX() 聯合使用,一般包含 GROUP BY 子句。
Hints
Impala SQL 方言支持查詢提示,用於微調查詢內部運做。由於缺乏統計信息或其餘因素致使效率低下的昂貴查詢,使用提示做爲臨時的解決辦法(Specify hints as a temporary workaround for expensive queries, where missing statistics or other factors cause inefficient performance)。所謂提示是指由方括號[]擴起的詞(The hints are represented as keywords surrounded by [] square brackets)。
目前全部的提示都是用於控制鏈接查詢的執行策略的(all the hints control the execution strategy for join queries)。在查詢的 JOIN 關鍵詞以後馬上緊跟如下結構之一:
覈對某一查詢的 EXPLAIN 的輸出信息,肯定該程序所採用的鏈接機制。
Note:
由於提示會阻止查詢利用新的元數據或改進的查詢計劃,所以僅當須要解決性能問題時使用,並隨時準備在不須要的時候刪除,好比 Impala 發佈新版本或修復 bug後。
例以下面的查詢鏈接一個大的客戶表(customer)和一個小的少於 100 行的表(lookup 表)。右側的表能夠高效的廣播到全部執行鏈接的節點。所以,你可使用 [broadcast] 提示強制採用關閉鏈接機制:
select customer.address, state_lookup.state_name
from customer join [broadcast] state_lookup
on (customer.state_id = state_lookup.state_id);
下面的查詢鏈接兩個位置大小的大表。你可能須要分別使用兩種查詢提示,肯定哪一種更有效的傳遞每一個表的一部分到全部其餘節點進行處理。所以,你可能使用 [shuffle] 提示強制使用分割鏈接機制:
select weather.wind_velocity, geospatial.altitude
from weather join [shuffle] geospatial
on (weather.lat = geospatial.lat and weather.long = geospatial.long);
對於執行三個以上表的鏈接,提示對它所在的 JOIN 兩側的表有效。鏈接操做從左到有進行處理。例如,下面的查詢使用分割鏈接表 t1 和 t2,而後使用廣播鏈接他們的鏈接結果和表 t3 :
select t1.name, t2.id, t3.price
from t1 join [shuffle] t2 join [broadcast] t3
on (t1.id = t2.id and t2.id = t3.id);
關於更多背景信息和性能跳轉的注意事項,參見 Joins。
當向分區表插入數據,特別是使用 Parquet 文件格式的分區表,你能夠在 INSERT 語句中使用提示來減小同時寫入 HDFS 的文件數量,以及保存不一樣分區數據的 1GB 內存緩存的數量。在表名以後緊跟 [SHUFFLE] 或 [NOSHUFFLE] 關鍵字。當試圖在全部節點上構建全部分區的結構數據而致使 INSERT 語句失敗或效率低下時,使用 [SHUFFLE] 提示(Put the hint keyword [SHUFFLE] or [NOSHUFFLE] immediately after the table name. Use [SHUFFLE] in cases where an INSERTstatement fails or runs inefficiently due to all nodes attempting to construct data for all partitions.)。此提示在 Impala 1.2.2 及以上版本可用
INSERT 語句
Impala 支持插入數據到表和分區中,這些表和分區既能夠是使用 Impala CREATE TABLE 語句建立,也能夠是經過 Hive 預先定義的表和分區。
Impala 目前支持:
Note:
Usage notes:
當向一個較小的數據列如 INT, SMALLINT, TINYINT, FLOAT 插入表達式的值,特別是調用內置函數時,可能須要使用 CAST() 進行轉換成對應的類型。Impala 對於較大的類型不會自動轉換成較小的類型。好比插入餘弦值到一個 FLOAT 列,應在 INSERT 語句中使用明確的轉換 CAST(COS(angle) AS FLOAT) 。
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
Important: 對於性能關鍵( performance-critical)查詢中用到的表,插入或替換數據以後,應執行 COMPUTE STATS 語句以確保全部統計信息是最新的。 在 Impala 中執行了 INSERT, LOAD DATA, CREATE TABLE AS SELECT 語句以後,或者在 Hive 中加載數據並在 Impala 中執行 REFRESH table_name以後, 應考慮更新表的統計信息。對於包含大量數據的表、用於鏈接查詢的表,這一技術特別重要 。
Statement type: DML (但仍受 SYNC_DDL 查詢選項影響)
例子:
下面的例子建立了一個與 Tutorial 中 TAB1 表相同定義而使用了不一樣的文件格式的新表,並演示如何插入數據到使用 STORED AS TEXTFILE 和 STORED AS PARQUET 子句建立的表中:
CREATE DATABASE IF NOT EXISTS file_formats;
USE file_formats;
DROP TABLE IF EXISTS text_table;
CREATE TABLE text_table
( id INT, col_1 BOOLEAN, col_2 DOUBLE, col_3 TIMESTAMP )
STORED AS TEXTFILE;
DROP TABLE IF EXISTS parquet_table;
CREATE TABLE parquet_table
( id INT, col_1 BOOLEAN, col_2 DOUBLE, col_3 TIMESTAMP )
STORED AS PARQUET;
使用 INSERT INTO TABLE 語法,每一組新插入的行都會追加到表現有數據以後。這是你如何記錄少許的持續到達數據,或提取顯存數據以外的新一批數據的方法(This is how you would record small amounts of data that arrive continuously, or ingest new batches of data alongside the existing data)。例如,在執行了 2 次插入 5 行記錄的插入語句以後,表中包含 10 行記錄:
[localhost:21000] > insert into table text_table select * from default.tab1;
Inserted 5 rows in 0.41s
[localhost:21000] > insert into table text_table select * from default.tab1;
Inserted 5 rows in 0.46s
[localhost:21000] > select count(*) from text_table;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
Returned 1 row(s) in 0.26s
使用 INSERT OVERWRITE TABLE 語法,每一組新插入的行替換掉表中原有的數據。這是你在數據倉庫場景,分析特定日期、季度等的數據同時丟棄以前的數據用於加載數據的查詢語句(This is how you load data to query in a data warehousing scenario where you analyze just the data for a particular day, quarter, and so on, discarding the previous data each time)。你可能在一個原始表中保存整個數據集,傳輸和轉換特定的行到一個對於深刻分析更緊湊更有效子集中(You might keep the entire set of data in one raw table, and transfer and transform certain rows into a more compact and efficient form to perform intensive analysis on that subset)
例如,下面顯示使用 INSERT INTO 子句插入了 5 行數據,而後使用 INSERT OVERWRITE 子句替換爲 3 行數據。這樣,表中只包含最終的 INSERT 語句插入的 3 行數據。
[localhost:21000] > insert into table parquet_table select * from default.tab1;
Inserted 5 rows in 0.35s
[localhost:21000] > insert overwrite table parquet_table select * from default.tab1 limit 3;
Inserted 3 rows in 0.43s
[localhost:21000] > select count(*) from parquet_table;
+----------+
| count(*) |
+----------+
| 3 |
+----------+
Returned 1 row(s) in 0.43s
使用 VALUES 子句容許你經過指定全部列的常量值向表中插入一行或多行。表達式的數量、類型和順序必須與表的定義匹配。
Note: INSERT ... VALUES 技術不適合載入大量的數據到基於 HDFS (HDFS-based)的表,由於插入操做沒法並行,而且每個語句產生單獨的數據文件。用於創建小尺寸的表(small dimension tables)或少許數據用於測試 SQL 語法或 HBase 表。不要用於大的 ETL做業或載入操做的基準測試。不要運行包含每次只插入單行數據的 數以千計的 INSERT ... VALUES 語句的腳本。假如在 ETL 操做中會產生不少小文件,那麼運行一個在一個 VALUES 子句中包含儘量多行數據的 INSERT .. VALUES 操做載入數據到一個臨時表,做爲整個 ETL 管道的一部分,並使用單獨的數據方便清理 (If you do run INSERT ... VALUES operations to load data into a staging table as one stage in an ETL pipeline, include multiple row values if possible within each VALUES clause, and use a separate database to make cleanup easier if the operation does produce many tiny files)
下面演示瞭如何插入一行或多行數據,其中使用不一樣類型的表達式,字符值,表達式和函數返回值:
create table val_test_1 (c1 int, c2 float, c3 string, c4 boolean, c5 timestamp);
insert into val_test_1 values (100, 99.9/10, 'abc', true, now());
create table val_test_2 (id int, token string);
insert overwrite val_test_2 values (1, 'a'), (2, 'b'), (-1,'xyzzy');
下面演示了 "not implemented" 錯誤,當你試圖向當前 Impala 不支持寫入的數據格式的表插入數據時會發生:
DROP TABLE IF EXISTS sequence_table;
CREATE TABLE sequence_table
( id INT, col_1 BOOLEAN, col_2 DOUBLE, col_3 TIMESTAMP )
STORED AS SEQUENCEFILE;
DROP TABLE IF EXISTS rc_table;
CREATE TABLE rc_table
( id INT, col_1 BOOLEAN, col_2 DOUBLE, col_3 TIMESTAMP )
STORED AS RCFILE;
[localhost:21000] > insert into table rc_table select * from default.tab1;
Remote error
Backend 0:RC_FILE not implemented.
[localhost:21000] > insert into table sequence_table select * from default.tab1;
Remote error
Backend 0:SEQUENCE_FILE not implemented.
根據分區列的不一樣,插入分區表的語法有略微的不一樣:
create table t1 (i int) partitioned by (x int, y string);
-- 從其餘表查詢出 INT 類型的列
-- 插入的全部行都具備相同的、在插入語句中指定的 x , y 值
insert into t1 partition(x=10, y='a') select c1 from some_other_table;
-- 從其餘表查詢出兩個 INT 列
-- 插入的全部行具備相同的、在插入語句中指定的 y 值
-- 存入 t1.x 的值是 some_other_table.c2
-- 沒有指定值的分區列會使用 SELECT 列表中最後的列來填充(插入分區列的順序與 SELECT 中的列的順序相同)
insert into t1 partition(x, y='b') select c1, c2 from some_other_table;
-- 從其餘表查詢出 INT 和 STRING 列
-- 插入的全部行具備相同的、在插入語句中指定的 x 值
-- 存入 t1.y 的值是 some_other_table.c3
insert into t1 partition(x=20, y) select c1, c3 from some_other_table;
下面例子演示了從一個表複製全部列到另外一個表,複製部分列,或在查詢列表中指定與表中列不一樣的順序:
-- 從 2 各項他的表開始
create table t1 (c1 int, c2 int);
create table t2 like t1;
-- 若是在目標表名以後沒有 () 部分,則全部列都必須指定,能夠用 * 或列名
insert into t2 select * from t1;
insert into t2 select c1, c2 from t1;
-- 使用了目標表後面的 () 標識,你能夠省略列(目標表中這些列的值設爲 NULL)
-- 且/或從新排序從原始表查詢的列。這就是"列置換(column permutation)"功能
insert into t2 (c1) select c1 from t1;
insert into t2 (c2, c1) select c1, c2 from t1;
-- 源表與目標表的列名能夠徹底不一樣
-- 你能夠從源表複製任意列而不僅是對應的列
-- 可是查詢出來的列的數量與類型必須與 () 部分中列的數據與類型一致
alter table t2 replace columns (x int, y int);
insert into t2 (y) select c1 from t1;
-- 對於分區表,全部的分區列都必須在 () 或 PARTITION 子句中列出;
-- 分區列不能默認爲空
create table pt1 (x int, y int) partitioned by (z int);
-- 新表中的列 x 使用 c1 的值
-- 都放入相同的、基於常數值 z 的分區
-- 新表中 y 的值我 NULL
insert into pt1 (x) partition (z=5) select c1 from t1;
-- 咱們一樣省略了 y 值,所以它們都是 NULL.
-- 插入的 x 值可能在不一樣的分區,根據分區列 z 的不一樣而不一樣
insert into pt1 (x,z) select x, z from t2;
併發性考慮: 每個 INSERT 操做都建立一個惟一名稱的新數據文件,所以能夠並行執行多個 INSERT INTO 語句而不會有文件名衝突。當數據被插入到 Impala 表後,數據被逐級臨時存放到數據目錄下的子目錄中(the data is staged temporarily in a subdirectory inside the data directory);在此期間,你沒法在 Hive 中執行該表的查詢。若是插入失敗,臨時數據文件和子目錄被拋棄在數據目錄中(If an INSERT operation fails, the temporary data file and the subdirectory could be left behind in the data directory)。這時候,經過執行 hdfs dfs -rm -r 命令,手工刪除對應的自目錄和數據文件,記得指定子目錄名的以 _dir 結尾的完整路徑。
INT 數據類型
4字節整數類型,用於 CREATE TABLE 和 ALTER TABLE 語句。
Range: -2147483648 .. 2147483647. There is no UNSIGNED subtype.
Conversions: Impala自動轉換爲更大的整數類型 (BIGINT) 或浮點數類型 (FLOAT , DOUBLE) 。轉換爲 TINYINT, SMALLINT,STRING 或 TIMESTAMP 須要使用 CAST() 函數。轉換整數值 N 爲 TIMESTAMP 時,是根據 Unix 紀元(January 1, 1970)開始的 N 秒來轉換。
數據類型 INTEGER 是 INT 的別名
Related information: TINYINT Data Type, BIGINT Data Type, SMALLINT Data Type, TINYINT Data Type, Mathematical Functions
內部表
CREATE TABLE 語句默認生成的表是內部表(internal table)。(與之對應的是外部表,由 CREATE EXTERNAL TABLE 語句生成)
INVALIDATE METADATA 語句
標記一個或全部的表的元數據爲陳舊的。當經過 Hive shell 建立了表以後,在 Impala 中查詢能夠訪問這個表以前須要執行此語句。當前 Impala 節點執行鍼對元數據無效的表的查詢以前,在下一次對這個表的查詢以前,Impala 會從新載入對應的元數據(The next time the current Impala node performs a query against a table whose metadata is invalidated, Impala reloads the associated metadata before the query proceeds)。與經過 REFRESH 語句進行增量元數據的更新比較,這是一個相對昂貴的操做,所以對於現存表中添加數據文件的場景,一般執行 REFRESH 操做而不是 INVALIDATE METADATA 操做(This is a relatively expensive operation compared to the incremental metadata update done by the REFRESH statement, so in the common scenario of adding new data files to an existing table, prefer REFRESH rather than INVALIDATE METADATA)。假如你不熟悉 Impala 使用元數據的方式以及如何與 Hive 共享相同的 metastore 數據庫的,參見 Overview of Impala Metadata and the Metastore 瞭解背景信息。
爲了準確的相應查詢,Impala 必須擁有關於客戶端直接查詢的數據庫和表的當前的元數據。所以,假如其餘實體修改了由 Impala 和 Hive 共享的被 Impala 使用的 metastore 的信息,Impala 緩存的相關信息必須進行更新。然而,這並不意味着 Impala 須要更新全部的元數據。
Note:
在 Impala 1.2 及以上版本,一個專門的守護進程(catalogd)負責廣播 Impala 產生的 DDL 變動到全部的 Impala 節點。以前,當你鏈接到一個 Impala 節點建立了一個數據庫或表以後,在其餘節點上訪問新的數據庫或表以前須要先執行 INVALIDATE METADATA 語句。如今,最新建立或修改的對象被全部節點自動得到。在 Hive 中建立或修改對象以後,仍然必須使用 INVALIDATE METADATA 技術。參見 The Impala Catalog Service 瞭解目錄服務的詳細信息。
INVALIDATE METADATA 語句是 Impala 1.1 開始引入,接替了 Impala 1.0 中 REFRESH 語句的一些功能。由於 REFRESH 須要一個表名參數,想要一次刷新全部表的元數據,須要使用 INVALIDATE METADATA 語句。
由於 REFRESH table_name 只對當前 Impala 節點已經承認的表有效,當你在 Hive 中建立了一個新表,你必須使用不帶參數的 INVALIDATE METADATA 而後才能在 impala-shell 中看到這個表。當表被 Impala 承認以後,在表上添加數據文件以後可使用 REFRESH table_name 語句。
INVALIDATE METADATA 和 REFRESH 是類似的(counterparts): INVALIDATE METADATA 等待並在後續查詢須要時重載所需的元數據,可是重載表的全部元數據是一個昂貴的操做,特別是對於具備許多分區的大表。REFRESH 當即重載元數據,可是隻載入新增長的數據文件的塊位置數據,使之成爲一個不太昂貴的操做。若是數據以一些更復雜的方式修改,例如 HDFS 平衡器(balancer) 重組,使用 INVALIDATE METADATA 來經過減小本地讀取來避免性能損失。如何使用 Impala 1.0,INVALIDATE METADATA 語句與 1.0 版本的 REFRESH 語句的執行相同的操做,而在 Impala 1.1 中 REFRESH 針對常見的爲已有表添加新數據文件的狀況進行了優化,所以當前須要表名參數。
INVALIDATE METADATA 命令的語法是:
INVALIDATE METADATA [table_name]
默認會刷新緩存的全部表的元數據。若是指定了表名,只刷新這個表的元數據。即便只針對一個表,INVALIDATE METADATA 也比 REFRESH 昂貴,所以對於已有表添加數據文件的狀況,應執行 REFRESH 操做。
發生如下狀況時須要更新 impalad 實例的元數據:
當你在執行了 ALTER TABLE,INSERT 或其餘的表修改語句的相同的 Impala 節點執行查詢時 不 須要更新元數據。
數據庫和表的元數據一般由下列語句修改:
INVALIDATE METADATA 致使表的元數據被標記爲過時的,並在表被下一次引用以前重載。對於巨大的表,這一過程可能須要至關的時間;所以你可能更願意用 REFRESH 執行加載來避免不可預知的延遲,例以下一次對錶的引用是在執行基準測試時。
下面的例子演示了在 Hive 中建立了新表後你可能使用 INVALIDATE METADATA 語句的狀況(例如 SequenceFile 或 HBase 表)。執行 INVALIDATE METADATA 語句以前,若是試圖訪問這些表,Impala 會返回 "table not found" 錯誤。 DESCRIBE 語句會致使這些表最新的元數據當即載入,避免了下次這些表查詢時的延遲。
[impalad-host:21000] > invalidate metadata;
[impalad-host:21000] > describe t1;
...
[impalad-host:21000] > describe t2;
...
關於 Impala 和 Hive 組合操做中更多使用 REFRESH 和 INVALIDATE METADATA 的例子,參見 Switching Back and Forth Between Impala and Hive。
假如你須要在啓動 impala-shell 會話以後確保元數據是最新的,使用帶有 -r 或 --refresh_after_connect 命令行選項的 impala-shell 。由於這一操做對每個表的下一查詢增長了延遲,對於有許多分區的大表潛在的昂貴,儘可能避免在生產環境的每日操做中使用該選項(Because this operation adds a delay to the next query against each table, potentially expensive for large tables with many partitions, try to avoid using this option for day-to-day operations in a production environment)
Joins
鏈接操做是一個組合兩個或多個表中的數據,並返回包含了一些或全部表中的項目的結果集操做(A join query is one that combines data from two or more tables, and returns a result set containing items from some or all of those tables)。一般如下狀況使用鏈接查詢:
Note: Impala 能夠鏈接不一樣文件格式的表,包括 Impala 管理表和 HBase 表。例如,你可能在 Hbase 表中保持小的維度表,以便單行查找和更新,使用 Parquet 或其餘針對掃描操做優化的二進制文件格式保存大的事實表。這樣,你能夠執行一個交叉引用維表和事實表的 鏈接查詢。
Note:
鏈接查詢的性能是 Impala 的重要方面,由於複雜的鏈接查詢是資源密集操做。一個有效的鏈接查詢比低效的鏈接查詢產生低得多的網絡傳輸和 CPU 負載。爲了最佳結果:
關於鏈接查詢性能的更多信息和例子,參見 Performance Considerations for Join Queries
鏈接查詢的結果集被包括在 ON/USING 子句中使用的對應的鏈接列名或 WHERE 子句中全部表的使用相等比較的列過濾(The result set from a join query is filtered by including the corresponding join column names in an ON or USING clause, or by using equality comparisons for columns from both tables in the WHERE clause)
[localhost:21000] > select c_last_name, ca_city from customer join customer_address where c_customer_sk = ca_address_sk;
+-------------+-----------------+
| c_last_name | ca_city |
+-------------+-----------------+
| Lewis | Fairfield |
| Moses | Fairview |
| Hamilton | Pleasant Valley |
| White | Oak Ridge |
| Moran | Glendale |
...
| Richards | Lakewood |
| Day | Lebanon |
| Painter | Oak Hill |
| Bentley | Greenfield |
| Jones | Stringtown |
+-------------+------------------+
Returned 50000 row(s) in 9.82s
鏈接查詢一個潛在的缺點就是不好的查詢結構致使的過量資源使用。例如,若是 T1 包含 1000 行而表 T2 包含 1,000,000 行,查詢 SELECT columns FROM t1 JOIN t2 會返回多達 10億行(1000 * 1,000,000)。爲了最大化減小大數據集上的失控的查詢出現的機會, Impala 要求每個鏈接查詢的不一樣表之間的列必須至少包含一個等值條件。
由於即便包含相等子句,結果集依然可能很大,像咱們在以前例子裏看到的,你可能須要使用 LIMIT 子句來返回一個結果集的子集:
[localhost:21000] > select c_last_name, ca_city from customer, customer_address where c_customer_sk = ca_address_sk limit 10;
+-------------+-----------------+
| c_last_name | ca_city |
+-------------+-----------------+
| Lewis | Fairfield |
| Moses | Fairview |
| Hamilton | Pleasant Valley |
| White | Oak Ridge |
| Moran | Glendale |
| Sharp | Lakeview |
| Wiles | Farmington |
| Shipman | Union |
| Gilbert | New Hope |
| Brunson | Martinsville |
+-------------+-----------------+
Returned 10 row(s) in 0.63s
或者使用額外的比較操做或聚合函數把一組大的結果集壓縮成小的結果集:
[localhost:21000] > -- 查找生活在指定小鎮的用戶名
[localhost:21000] > select distinct c_last_name from customer, customer_address where
c_customer_sk = ca_address_sk
and ca_city = "Green Acres";
+---------------+
| c_last_name |
+---------------+
| Hensley |
| Pearson |
| Mayer |
| Montgomery |
| Ricks |
...
| Barrett |
| Price |
| Hill |
| Hansen |
| Meeks |
+---------------+
Returned 332 row(s) in 0.97s
[localhost:21000] > -- 查看這個小鎮上有多少用戶名以"A"開頭
[localhost:21000] > select count(distinct c_last_name) from customer, customer_address where
c_customer_sk = ca_address_sk
and ca_city = "Green Acres"
and substr(c_last_name,1,1) = "A";
+-----------------------------+
| count(distinct c_last_name) |
+-----------------------------+
| 12 |
+-----------------------------+
Returned 1 row(s) in 1.00s
由於鏈接查詢可能包括從硬盤上讀取大量的數據,經過網絡發送大量的數據,載入大量的數據到內存中進行比較和過濾,你可能須要作基準測試,性能分析和查詢優化,以找出對你的數據集、硬件容量、網絡配置和集羣負載最優的鏈接查詢。
Impala 支持兩類鏈接 partitioned joins 和 broadcast joins。假如表和列的統計信息不許確,或數據分佈的傾斜(some quirk of the data distribution),致使 Impala 對特定的鏈接選擇了錯誤的機制,考慮使用查詢提示做爲臨時的解決辦法。詳細信息參見 Hints。
查看教程中不一樣種類鏈接的例子:
LIKE 運算符
一種字符串(STRING)數據的比較運算符,包含基本的通配符能力,使用 _ 匹配單個字符, % 匹配多個字符。參數表達式必須匹配整個字符串的值。一般把通配符 % 放在字符串結尾效率更高( it is more efficient to put any % wildcard match at the end of the string.)
例子:
select distinct c_last_name from customer where c_last_name like 'Mc%' or c_last_name like 'Mac%';
select count(c_last_name) from customer where c_last_name like 'M%';
select c_email_address from customer where c_email_address like '%.edu';
-- 咱們能夠經過調用函數找到 4 個字母而且以 'M' 開頭的名字...
select distinct c_last_name from customer where length(c_last_name) = 4 and substr(c_last_name,1,1) = 'M';
-- ...或者使用更易讀的方式匹配 M 後面跟着 3 個字母
select distinct c_last_name from customer where c_last_name like 'M___';
關於使用正則表達式的更通用的查找操做,參見 REGEXP Operator.
LIMIT 子句
SELECT 查詢中的 LIMIT 子句設置結果集中的最大行數。在如下場景有用:
Usage notes:
原先 LIMIT 子句必須使用數字,在 Impala 1.2.1 及以上版本,能夠是數字表達式。
Impala 要求任意的包含 ORDER BY 子句的查詢同時使用 LIMIT 子句。由於排序海量結果集須要如此多的內存,而對 Impala 來講 top-N 查詢如此常見,這一子句的組合防止意外的查詢致使協調器節點上的內存消耗過大。你能夠指定 LIMIT 子句做爲查詢的一部分,或者在 impala-shell 裏經過命令 SET DEFAULT_ORDER_BY_LIMIT=... 爲會話的全部查詢設置一個默認限制,或者以 -default_query_options default_order_by_limit=... 選項啓動 impalad 以設置實例級別的限制。
參見 ORDER BY Clause 瞭解詳細信息,和爲了不在每個 ORDER BY 查詢中添加明確的 LIMIT 子句可用的查詢選項。
在 Impala 1.2.1 及以上版本,你能夠結合 LIMIT 子句和 OFFSET 子句,產生一個與 top-N 查詢不一樣的小結果集,例如,返回 11 到 20 的項目。這種技術能夠用於模擬 "分頁(paged)" 結果集。由於 Impala 查詢一般包括大量的 I/O 操做,僅在你不能重寫應用邏輯爲了兼容性而使用此技術。爲了最佳性能和擴展性,不管現實,查詢你指望須要的,並緩存到應用端,並使用應用邏輯顯示小組的結果集。
例子:
下面的例子演示 LIMIT 子句如何限制結果集,它在其餘子句如 WHERE 以後生效(The following example shows how the LIMIT clause caps the size of the result set, with the limit being applied after any other clauses such as WHERE)。
[localhost:21000] > create database limits;
[localhost:21000] > use limits;
[localhost:21000] > create table numbers (x int);
[localhost:21000] > insert into numbers values (1), (3), (4), (5), (2);
Inserted 5 rows in 1.34s
[localhost:21000] > select x from numbers limit 100;
+---+
| x |
+---+
| 1 |
| 3 |
| 4 |
| 5 |
| 2 |
+---+
Returned 5 row(s) in 0.26s
[localhost:21000] > select x from numbers limit 3;
+---+
| x |
+---+
| 1 |
| 3 |
| 4 |
+---+
Returned 3 row(s) in 0.27s
[localhost:21000] > select x from numbers where x > 2 limit 2;
+---+
| x |
+---+
| 3 |
| 4 |
+---+
Returned 2 row(s) in 0.27s
對於 top-N 查詢,應同時使用 ORDER BY 和 LIMIT 子句。假如你已經設置了 DEFAULT_ORDER_BY_LIMIT 查詢選項,這樣你不須要明確的在每一個包含 ORDER BY 的查詢添加 LIMIT 子句。你也能夠同時設置 ABORT_ON_DEFAULT_LIMIT_EXCEEDED 查詢選項以免意外截斷結果集。
[localhost:21000] > select x from numbers order by x;
ERROR: NotImplementedException: ORDER BY without LIMIT currently not supported
[localhost:21000] > set default_order_by_limit=1000;
DEFAULT_ORDER_BY_LIMIT set to 1000
[localhost:21000] > select x from numbers order by x;
+---+
| x |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+---+
Returned 5 row(s) in 0.35s
[localhost:21000] > set abort_on_default_limit_exceeded=true;
ABORT_ON_DEFAULT_LIMIT_EXCEEDED set to true
[localhost:21000] > set default_order_by_limit=3;
DEFAULT_ORDER_BY_LIMIT set to 3
[localhost:21000] > select x from numbers order by x;
ERROR: DEFAULT_ORDER_BY_LIMIT has been exceeded.
Cancelling query ...
LOAD DATA 語句
LOAD DATA 語句簡化了 Impala 內部表從 HDFS 位置移動一個或目錄下全部數據文件到該表對應的 Impala 數據目錄中的 ETL 過程(The LOAD DATA statement streamlines the ETL process for an internal Impala table by moving a data file or all the data files in a directory from an HDFS location into the Impala data directory for that table)。
語法:
LOAD DATA INPATH 'hdfs_file_or_directory_path' [OVERWRITE] INTO TABLE tablename
[PARTITION (partcol1=val1,partcol2=val2...)]
Usage Notes:
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
Important: 對於性能關鍵( performance-critical)查詢中用到的表,插入或替換數據以後,應執行 COMPUTE STATS 語句以確保全部統計信息是最新的。 在 Impala 中執行了 INSERT, LOAD DATA, CREATE TABLE AS SELECT 語句以後,或者在 Hive 中加載數據並在 Impala 中執行 REFRESH table_name以後, 應考慮更新表的統計信息。對於包含大量數據的表、用於鏈接查詢的表,這一技術特別重要 。
例子:
首先,咱們使用一個簡單的 Python 腳本寫入不一樣數量的字符串(每行一個)到存儲在 cloudera HDFS 用戶下的文件裏(當執行相似的 hdfs dfs 操做時替換爲你本身的 HDFS 用戶賬號)。
$ random_strings.py 1000 | hdfs dfs -put - /user/cloudera/thousand_strings.txt
$ random_strings.py 100 | hdfs dfs -put - /user/cloudera/hundred_strings.txt
$ random_strings.py 10 | hdfs dfs -put - /user/cloudera/ten_strings.txt
接下來,咱們建立一個表並加載一組初始化數據到裏面。記住,除非你指定了 STORED AS 子句,Impala 表默認是用 Ctrl-A(\01) 做爲字段分隔符的 TEXTFILE 格式。這個例子使用單列的表,所以分隔符無所謂。對於大規模的 ETL 做業,你可能一般使用二進制格式的數據文件,如 Parquet 或 Avro,並使用對應的文件格式把它們加載到Impala 表中。
[localhost:21000] > create table t1 (s string);
[localhost:21000] > load data inpath '/user/cloudera/thousand_strings.txt' into table t1;
Query finished, fetching results ...
+----------------------------------------------------------+
| summary |
+----------------------------------------------------------+
| Loaded 1 file(s). Total files in destination location: 1 |
+----------------------------------------------------------+
Returned 1 row(s) in 0.61s
[kilo2-202-961.cs1cloud.internal:21000] > select count(*) from t1;
Query finished, fetching results ...
+------+
| _c0 |
+------+
| 1000 |
+------+
Returned 1 row(s) in 0.67s
[localhost:21000] > load data inpath '/user/cloudera/thousand_strings.txt' into table t1;
ERROR: AnalysisException: INPATH location '/user/cloudera/thousand_strings.txt' does not exist.
如前面例子最後顯示的信息標識的,數據文件已經從它原始的位置被移走。下面的例子展現了數據文件已經被移動到目標表的 Impala 數據目錄,並保留原有的文件名:
$ hdfs dfs -ls /user/hive/warehouse/load_data_testing.db/t1
Found 1 items
-rw-r--r-- 1 cloudera cloudera 13926 2013-06-26 15:40 /user/hive/warehouse/load_data_testing.db/t1/thousand_strings.txt
下面的例子演示了 INTO TABLE 和 OVERWRITE TABLE 子句的不一樣。表中已經有 1000 條記錄。當執行了包含 INTO TABLE 子句的 LOAD DATA 語句後,表中增長了 100 行,總共 1100 行。而當執行了包含 OVERWRITE INTO TABLE 子句的 LOAD DATA 語句後,以前的內容沒有了,如今表中只包含剛加載的數據文件中的 10 行記錄。
[localhost:21000] > load data inpath '/user/cloudera/hundred_strings.txt' into table t1;
Query finished, fetching results ...
+----------------------------------------------------------+
| summary |
+----------------------------------------------------------+
| Loaded 1 file(s). Total files in destination location: 2 |
+----------------------------------------------------------+
Returned 1 row(s) in 0.24s
[localhost:21000] > select count(*) from t1;
Query finished, fetching results ...
+------+
| _c0 |
+------+
| 1100 |
+------+
Returned 1 row(s) in 0.55s
[localhost:21000] > load data inpath '/user/cloudera/ten_strings.txt' overwrite into table t1;
Query finished, fetching results ...
+----------------------------------------------------------+
| summary |
+----------------------------------------------------------+
| Loaded 1 file(s). Total files in destination location: 1 |
+----------------------------------------------------------+
Returned 1 row(s) in 0.26s
[localhost:21000] > select count(*) from t1;
Query finished, fetching results ...
+-----+
| _c0 |
+-----+
| 10 |
+-----+
Returned 1 row(s) in 0.62s
Statement type: DML (但仍受 SYNC_DDL 查詢選項影響)
MAX 函數
返回一組數值中最大值的聚合函數。與 MIN 函數相反。它惟一的參數能夠是數值列,或者列值上的函數或表達式的數值結果。輸入列中 NULL 的行被忽略。假如表爲空,或者提供給 MAX 函數的全部值都爲 NULL,則返回 NULL。
當查詢包含 GROUP BY 子句時,對分組值的每一種組合返回一個值。
Return type: 與輸入參數相同類型
Examples:
-- 查找 t1 表中 c1 列的最大值
select max(c1) from t1;
-- 查找 t1 表中 2013 年 1 月的 c1 列的最大值
select max(c1) from t1 where month = 'January' and year = '2013';
-- 查找 t1 表中 s 列的最大長度
select max(length(s)) from t1;
-- 可與 DISTINCT 和/或 GROUP BY 同時使用
-- 返回多個結果
select month, year, max(purchase_price) from store_stats group by month, year;
-- 在執行計算以前,過濾輸入中的重複值
select max(distinct x) from t1;
MIN 函數
返回一組數值中最小值的聚合函數。與 MAX 函數相反。它惟一的參數能夠是數值列,或者列值上的函數或表達式的數值結果。輸入列中 NULL 的行被忽略。假如表爲空,或者提供給 MIN 函數的全部值都爲 NULL,則返回 NULL。
當查詢包含 GROUP BY 子句時,對分組值的每一種組合返回一個值。
Return type: 與輸入參數相同類型
Examples:
-- Find the smallest value for this column in the table.
select min(c1) from t1;
-- Find the smallest value for this column from a subset of the table.
select min(c1) from t1 where month = 'January' and year = '2013';
-- Find the smallest value from a set of numeric function results.
select min(length(s)) from t1;
-- Can also be used in combination with DISTINCT and/or GROUP BY.
-- Return more than one result.
select month, year, min(purchase_price) from store_stats group by month, year;
-- Filter the input to eliminate duplicates before performing the calculation.
select min(distinct x) from t1;
NDV 函數
返回相似於 COUNT(DISTINCT col) "不一樣值的數量(number of distinct values)" 結果的近似值的聚合函數。它比 COUNT 和 DISTINCT 組合的速度更快,並使用固定大小的內存,所以對於高基數的列更少的內存消耗(thus is less memory-intensive for columns with high cardinality)
這是內部 COMPUTE STATS 語句計算列的不一樣值數量所採用的機制。
Usage notes:
由於數量是估計的,它可能不會精確反映列的不一樣值,特別是基數很是低或很是高時。如何估計值比表中的行數高, Impala 在查詢規劃期間會內部調整這個值。
Return type: BIGINT
NULL
各類數據庫中都有熟悉的 NULL 概念,可是每一種 SQL 方言可能對 NULL 有本身獨有的行爲和限制。對於大數據處理,NULL 值的精確語義很重要:任何誤解均可能致使不正確的結果或錯誤格式的(misformatted)數據,修正這一數據對於大數據集至關耗時。
Note: 由於在當前 Hive 查詢中 NULLS FIRST 和 NULLS LAST 關鍵字不可用,你使用這些關鍵字建立的視圖在 Hive 中都不可用
OFFSET 子句
SELECT 查詢中的 OFFSET 子句會致使結果集從邏輯上的第一行後某些數值以後的行開始。結果集從 0 開始編號,所以 OFFSET 0 與不使用 OFFSET 子句的查詢生成相同的結果集。老是在包含 ORDER BY (以便清楚哪一項目是第一個、第二個、等等) 和 LIMIT (這樣結果集涵蓋了有限的範圍,如第 0-9 行, 100-199 行,等等) 組合的語句中使用此子句
在 Impala 1.2.1 及以上版本,你能夠結合 LIMIT 子句和 OFFSET 子句,產生一個與 top-N 查詢不一樣的小結果集,例如,返回 11 到 20 的項目。這種技術能夠用於模擬 "分頁(paged)" 結果集。由於 Impala 查詢一般包括大量的 I/O 操做,僅在你不能重寫應用邏輯爲了兼容性而使用此技術。爲了最佳性能和擴展性,不管現實,查詢你指望須要的,並緩存到應用端,並使用應用邏輯顯示小組的結果集。
Examples:
下面例子演示瞭如何運行一個原來爲傳統數據庫應用寫的"分頁(paging)"查詢。由於一般 Impala 查詢處理成 M 或 G 的數據,每一次從硬盤讀取大量的數據文件,運行一個單獨的查詢來獲取每一組少許的項目是低效的。僅當爲了移植舊的應用保持兼容性時使用此技術,而後重寫應用代碼使用返回大結果集的單個查詢,並從緩存數據中顯示分頁結果集。
[localhost:21000] > create table numbers (x int);
[localhost:21000] > insert into numbers select x from very_long_sequence;
Inserted 1000000 rows in 1.34s
[localhost:21000] > select x from numbers order by x limit 5 offset 0;
+----+
| x |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
Returned 5 row(s) in 0.26s
[localhost:21000] > select x from numbers order by x limit 5 offset 5;
+----+
| x |
+----+
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+
Returned 5 row(s) in 0.23s
ORDER BY 子句
熟悉的 SELECT 查詢中的 ORDER BY 子句基於一個或多個列的值排序結果集。對於分佈式查詢,這是一個至關昂貴的操做,由於整個結果集在執行排序以前必須被處理和傳輸到一個節點上。相比不使用 ORDER BY 子句,這將須要更多的內存容量。即便使用和不使用 ORDER BY 子句的查詢須要大約相同的時間來完成,主觀上也會感受它出現的更慢,由於直處處理完成纔有結果可用,而不是一當匹配了 WHERE 子句結果集就逐漸回來。
ORDER BY 子句的完整語法是:
ORDER BYcol1[,col2...] [ASC | DESC] [NULLS FIRST | NULLS LAST]
默認的排序 (與使用 ASC 關鍵字相同) 把最小的值放在結果集的開始位置,最大值在結束位置。使用 DESC 關鍵字逆轉這一順序。
參見 NULL 瞭解 NULL 值在排序的結果集中如何定位,以及如何使用 NULLS FIRST 和 NULLS LAST 子句 (在 Impala 1.2.1 開始的NULL 值在 ORDER BY ... DESC 查詢中位置的改變動兼容標準,而且新增了 NULLS FIRST 和 NULLS LAST 關鍵字)
Impala 要求任意的包含 ORDER BY 子句的查詢同時使用 LIMIT 子句。由於排序海量結果集須要如此多的內存,而對 Impala 來講 top-N 查詢如此常見,這一子句的組合防止意外的查詢致使協調器節點上的內存消耗過大。你能夠指定 LIMIT 子句做爲查詢的一部分,或者在 impala-shell 裏經過命令 SET DEFAULT_ORDER_BY_LIMIT=... 爲會話的全部查詢設置一個默認限制,或者以 -default_query_options default_order_by_limit=... 選項啓動 impalad 以設置實例級別的限制。
參見 SELECT Statement 中更多查詢中使用 ORDER BY 子句的例子。關於能夠用來微調 ORDER BY 子句的行爲,避免修改你的 SQL 語句添加明確的 LIMIT 子句的查詢選項,參見 DEFAULT_ORDER_BY_LIMIT and ABORT_ON_DEFAULT_LIMIT_EXCEEDED。
REFRESH 語句
爲了準確的相應查詢,做爲協調器的 Impala 節點(你經過 impala-shell, JDBC, ODBC 鏈接的節點) 必須擁有查詢中引用的表和數據庫當前的元數據。假如你不熟悉 Impala 如何使用元數據以及它與 Hive 共享的相同 metastore 數據庫,請參考 Overview of Impala Metadata and the Metastore 瞭解背景信息。
在如下場景,使用 REFRESH 語句加載特定表最新的 metastore 元數據和 塊位置數據(block location data):
你只須要在你鏈接並執行查詢的節點執行 REFRESH 語句。協調器節點在集羣中的 Impala 節點之間拆分工做,併發送正確的 HDFS 塊的讀取請求,不須要依賴其餘節點上的元數據。
REFRESH 從 metastore 數據庫從新載入表的元數據,並對新添加到表的 HDFS 數據目錄中的任意新數據文件的底層塊位置執行增量的重載(and does an incremental reload of the low-level block location data to account for any new data files added to the HDFS data directory for the table)。它是低開銷、單表的操做,針對 HDFS 中新添加的數據文件這一經常使用場景作了特別優化。
REFRESH 命令的語法爲:
REFRESH table_name
只有指定表的元數據被刷新。該表必須已經存在而且對 Impala 已知,或者是由於是在 Impala 而不是 Hive 中運行的 CREATE TABLE 語句,或者是由於前一個 INVALIDATE METADATA 語句致使 Impala 重載了整個元數據目錄。
Note:
在 Impala 1.2 及以上版本,Impala 中做爲 ALTER TABLE, INSERT 和 LOAD DATA 語句的結果而致使的元數據的任意變化,目錄服務廣播到全部 Impala 節點。所以僅當你經過 Hive 加載數據或直接在 HDFS 中操做數據文件後,才須要執行 REFRESH 語句。參考 The Impala Catalog Service 瞭解目錄服務的詳細信息。
在 Impala 1.2.1 及以上版本,另外一種避免各個節點的數據不一致的方法是在執行 DDL 語句、 INSERT 、 LOAD DATA 語句前啓用 SYNC_DDL 查詢選項。
REFRESH 語句的功能在 Impala 1.1 之後發生了變化。如今須要傳遞表名參數。使用 INVALIDATE METADATA 命令刷新全部表的元數據。
由於 REFRESH table_name 只能對已經被 Impala 感知的表工做,當你在 Hive 中建立了新表以後,你必須先執行不包含參數的 INVALIDATE METADATA 語句,而後才能在 impala-shell 中看到這個表。當這個表被 Impala 感知以後,就能夠在表添加數據文件以後執行 REFRESH table_name 語句。
INVALIDATE METADATA 和 REFRESH 是類似的(counterparts): INVALIDATE METADATA 等待並在後續查詢須要時重載所需的元數據,可是重載表的全部元數據是一個昂貴的操做,特別是對於具備許多分區的大表。REFRESH 當即重載元數據,可是隻載入新增長的數據文件的塊位置數據,使之成爲一個不太昂貴的操做。若是數據以一些更復雜的方式修改,例如 HDFS 平衡器(balancer) 重組,使用 INVALIDATE METADATA 來經過減小本地讀取來避免性能損失。如何使用 Impala 1.0,INVALIDATE METADATA 語句與 1.0 版本的 REFRESH 語句的執行相同的操做,而在 Impala 1.1 中 REFRESH 針對常見的爲已有表添加新數據文件的狀況進行了優化,所以當前須要表名參數。
發生如下狀況時須要更新 impalad 實例的元數據:
當你在 Impala 而不是 Hive 中執行了 ALTER TABLE,INSERT 或其餘的表修改語句的時候 不 須要更新元數據。
數據庫和表的元數據一般由如下語句修改:
使用 REFRESH 子句後表的元數據被當即重載。對巨大的表, 這一過程可能花費大量的時間;可是應當執行刷新操做以免不可預知的延遲,例如你是在下面的基準測試中引用這個表。
假如爲了負載均衡的緣由,在 impala-shell 會話中鏈接到了不一樣的 Impala 節點,能夠啓用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被全部 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
Examples:
下面的例子演示了可能使用 REFRESH 語句的狀況,在手工向 Impala 數據目錄添加了 HDFS 數據文件以後:
[impalad-host:21000] > refresh t1;
[impalad-host:21000] > refresh t2;
[impalad-host:21000] > select * from t1;
...
[impalad-host:21000] > select * from t2;
...
關於 Impala 和 Hive 組合操做中更多使用 REFRESH 和 INVALIDATE METADATA 的例子,參見 Switching Back and Forth Between Impala and Hive。
Statement type: DDL
Related impalad options:
在 Impala 1.0 中,impala-shell 的 -r 選項會執行 REFRESH 操做重載全部表的元數據。
在 Impala 1.1 及以上版本,這一選項執行 INVALIDATE METADATA 語句,由於 REFRESH 當前須要表名參數。由於重載全部表的元數據很昂貴,因此儘可能避免在生產環境的每日操做中使用該選項。
在 Impala 1.2 及以上版本,須要 -r 選項的狀況更少,由於 Impala 中 SQL 語句致使的元數據修改會自動廣播到全部節點。
Important: 對於性能關鍵( performance-critical)查詢中用到的表,插入或替換數據以後,應執行 COMPUTE STATS 語句以確保全部統計信息是最新的。 在 Impala 中執行了 INSERT, LOAD DATA, CREATE TABLE AS SELECT 語句以後,或者在 Hive 中加載數據並在 Impala 中執行 REFRESH table_name以後, 應考慮更新表的統計信息。對於包含大量數據的表、用於鏈接查詢的表,這一技術特別重要 。
REGEXP 操做符
測試一個值是否匹配正則表達式。使用 POSIX 正則表達式語法,其中 ^ 和 $ 在正則表達式開始和結束(Uses the POSIX regular expression syntax where ^ and $ match the beginning and end of the string), . 對應任意單個字母, * 表明 0 個或多個項目的序列, + 對應出現一次或屢次項目的序列, ? 產生一次非貪婪的匹配,如此等等。
正則表達式必須匹配完整的值,而不只僅是其中的部份內容。假如你只須要匹配出如今中間任意部分的字符,在正則的開始和/或最後使用 .* 。所以,^ 和 $ 一般是多餘的,儘管你可能已經在你重用的其餘地方的正則表達式中包含它們(although you might already have them in your expression strings that you reuse from elsewhere)
RLIKE 操做符是 REGEXP 的同義詞。
豎線 | 是間隔符,一般在括號 () 中使用以匹配不一樣的序列。括號 () 中的組不容許反向引用(backreferences)。使用 regexp_extract() 內置函數獲取括號()中匹配的那部份內容。
Examples:
-- 查找 first name 以 'J' 開頭, 以後能夠跟 0 或更多個字母
select c_first_name, c_last_name from customer where c_first_name regexp 'J.*';
-- 查找 'Macdonald', 其中第一個 'a' 是可選的, 'D' 能夠是大寫也能夠是小寫
-- ^...$ 不是必需的,但使整個表達式看起來很清晰
select c_first_name, c_last_name from customer where c_last_name regexp '^Ma?c[Dd]onald$';
-- 查找 'Macdonald' 或 'Mcdonald'
select c_first_name, c_last_name from customer where c_last_name regexp '(Mac|Mc)donald';
-- 查找 last name 以 'S' 開始, 而後是一個或多個的元音,而後是 'r', 而後是其餘任意字符
-- 匹配 'Searcy', 'Sorenson', 'Sauer'.
select c_first_name, c_last_name from customer where c_last_name regexp 'S[aeiou]+r.*';
-- 查找 last name 以 2 個或多個元音結束:是 a,e,i,o,u 之一的字符
select c_first_name, c_last_name from customer where c_last_name regexp '.*[aeiou]{2,}$';
-- 你可使用 [] 塊中字母的範圍開頭,例如查找 last name 以 A, B, C 開頭的
select c_first_name, c_last_name from customer where c_last_name regexp '[A-C].*';
-- 假如你不肯定大小寫,前導或末尾的空格等等,能夠先在列上執行字符串函數進行處理
select c_first_name, c_last_name from customer where lower(c_last_name) regexp 'de.*';
RLIKE 操做符
REGEXP 操做符的同義詞
SELECT 語句
Impala SELECT 查詢支持:
Note:
ORDER BY 查詢須要限制結果集的條數。能夠在啓動 Impala 時設置這一限制,也能夠在 Impala shell 中設置。目前不支持經過 ODBC 和 JDBC 設置查詢選項,所以你使用這些鏈接方式,在啓動 Impala 時設置這一限制。例如使用相似下面的命令在 shell 中設置這一值:
[impalad-host:21000] > set default_order_by_limit=50000
當啓動 Impala 時,對 impalad 守護進程使用包含 -default_query_option 啓動參數。例如,使用相似下面的命令啓動 impala爲 ORDER BY 查詢設置限制:
$ GLOG_v=1 nohup impalad -state_store_host=state_store_hostname-hostname=impalad_hostname-default_query_options default_order_by_limit=50000
SHOW 語句
SHOW 子句是一種靈活的獲取 Impala 中不一樣種類對象信息的方式。你能夠運行 SHOW object_type 語句來查看當前數據庫中對應的對象,或運行 SHOW object_type IN database_name 來查看特定數據庫中的對象。
執行如下語句,顯示特定種類全部可用對象的列表:
Usage notes:
SHOW DATABASES 語句一般是第一次鏈接到一個實例後執行的第一個語句。一般執行 SHOW DATABASES 查看能夠在 USE db_namestatement 中使用的數據庫,當切換數據庫以後執行 SHOW TABLES 查看你能夠在 SELECT 和 INSERT 語句中使用的名稱。
隨着時間的推移模式的變化,你可能運行 CREATE TABLE 語句而後跟着幾個 ALTER TABLE 語句。爲了捕獲這些語句累積的效果,SHOW CREATE TABLE 顯示了重現當前表結構對應的 CREATE TABLE 語句。你能夠在腳本中使用這一輸出來設置或克隆一組表,而不是從新執行原始的那一組 CREATE TABLE 和 ALTER TABLE 語句。當建立變化的原始表,或在不一樣的系統克隆一個原始表時,你可能須要修改 SHOW CREATE TABLE 輸出中如數據庫名、 LOCATION 字段以及其餘在目標系統上不一樣的部分。
SHOW FUNCTIONS 的輸出包括每一個函數的參數簽名。在使用 DROP FUNCTION 語句時須要指定這一函數的參數簽名。你可能會有幾個具備相同名稱、接受不一樣類型參數的 UDFs。
當啓用受權後,SHOW 語句輸出被限制爲你具備權限的對象。那裏可能有其餘的數據庫、表或其餘的等等,但名字是隱藏的。若是你認爲對象存在可是在 SHOW 輸出中沒法看到,請讓系統管理員授予你這些對象所需的權限。參見 Using Authorization with Impala 瞭解特定種類的對象如何創建受權和權限。
Examples:
下面例子演示了在一個不熟悉的系統中如何定位一個特定的表。初始鏈接的是 DEFAULT 數據庫;一個在全部系統中都存在的數據庫。你能夠不切換到對應的數據庫就執行 SHOW TABLES IN db_name 語句,或切換到特定的數據庫後執行 SHOW TABLES 語句。
[localhost:21000] > show databases;
+--------------------+
| name |
+--------------------+
| analyze_testing |
| avro |
| ctas |
| d1 |
| d2 |
| d3 |
| default |
| file_formats |
| hbase |
| load_data |
| partitioning |
| regexp_testing |
| reports |
| temporary |
+--------------------+
Returned 14 row(s) in 0.02s
[localhost:21000] > show tables in file_formats;
+--------------------+
| name |
+--------------------+
| parquet_table |
| rcfile_table |
| sequencefile_table |
| textfile_table |
+--------------------+
Returned 4 row(s) in 0.01s
[localhost:21000] > use file_formats;
[localhost:21000] > show tables;
+--------------------+
| name |
+--------------------+
| parquet_table |
| rcfile_table |
| sequencefile_table |
| textfile_table |
+--------------------+
Returned 4 row(s) in 0.01s
SMALLINT 數據類型
2字節整數類型,用於 CREATE TABLE 和 ALTER TABLE 語句
Range: -32768 .. 32767. 不包括無符號子類型
Conversions: Impala自動轉換爲更大的整數類型 (INT, BIGINT) 或浮點數類型 (FLOAT , DOUBLE) 。轉換爲 TINYINT,STRING 或 TIMESTAMP 須要使用 CAST() 函數。轉換整數值 N 爲 TIMESTAMP 時,是根據 Unix 紀元(January 1, 1970)開始的 N 秒來轉換。
Related information: TINYINT Data Type, BIGINT Data Type, TINYINT Data Type, INT Data Type, Mathematical Functions
STRING 數據類型
一種用於 CREATE TABLE 和 ALTER TABLE 語句的數據類型。
Length: 32,767 字節(嚴格地說。最大長度對應 C/C++ 常數 INT_MAX,在 Linux 系統中一般是 32,767)。在定義 STRING 列時不要使用任何長度限制約束,就像你可能在關係數據庫系統中熟悉的 VARCHAR, CHAR, 或相似的列類型。
Character sets: 爲了全部的 Impala 子系統都支持,限制字符串的值爲 ASCII 碼集。UTF-8 字符數據能夠被 Impala 存儲並經過查詢獲取,可是對於包含非 ASCII(non-ASCII) 字符的 UTF-8 字符串,不保證字符串操做函數、計算操做、或 ORDER BY 子句能正常工做。For any national language aspects such as collation order or interpreting extended ASCII variants such as ISO-8859-1 or ISO-8859-2 encodings, Impala does not include such metadata with the table definition. 假如你須要排序、操做、或顯示依賴於這些國家語言特色(national language characteristics)的字符串數據,請在客戶端實現此邏輯。
轉換:
Related information: String Functions, Date and Time Functions
SUM 函數
返回一組數值的和的聚合函數。它惟一的參數能夠是數值列,或者列值上的函數或表達式的數值結果。輸入列中 NULL 的行被忽略。假如表爲空,或者提供給 SUM 函數的全部值都爲 NULL,則返回 NULL。
當查詢包含 GROUP BY 子句時,對分組值的每一種組合返回一個值。
Return type: 輸入參數是整數,則返回 BIGINT,輸入參數是浮點數,則返回 DOUBLE
Examples:
-- Total all the values for this column in the table.
select sum(c1) from t1;
-- Find the total for this column from a subset of the table.
select sum(c1) from t1 where month = 'January' and year = '2013';
-- Find the total from a set of numeric function results.
select sum(length(s)) from t1;
-- Often used with functions that return predefined values to compute a score.
select sum(case when grade = 'A' then 1.0 when grade = 'B' then 0.75 else 0) as class_honors from test_scores;
-- Can also be used in combination with DISTINCT and/or GROUP BY.
-- Return more than one result.
select month, year, sum(purchase_price) from store_stats group by month, year;
-- Filter the input to eliminate duplicates before performing the calculation.
select sum(distinct x) from t1;
TIMESTAMP 數據類型
用於 CREATE TABLE 和 ALTER TABLE 語句的數據類型,對應一個時間點。
Range: 在內部, TIMESTAMP 值中時間部分的精度是納秒
Time zones: Impala 不支持保存本地時區的時間戳,爲了不由於意外的時區問題致使的未知的結果。時間戳都是相對 GMT 保存的。
Conversions: Impala 自動轉換正確格式的 STRING 字面值爲 TIMESTAMP 值。 Timestamp 值接受 YYYY-MM-DD HH:MM:SS.sssssssss 格式,能夠只包含日期,或者只包含時間,帶或不帶第二部分的小數部分。例如,你能夠設置 TIMESTAMP 值爲 '1966-07-30', '08:30:00', '1985-09-25 17:45:30.005'。也能夠轉換整數或浮點數 N 爲 TIMESTAMP,生成一個自 UNIX 紀元開始的 N 秒值對應的時間戳(January 1, 1970)。
Partitioning:
儘管不能使用 TIMESTAMP 做爲分區鍵,但能夠提取單獨的年、月、日、小時、等等並基於這些分區。由於分區鍵列的值在 HDFS 目錄名中表示,而不是數據文件中的字段表示,若是須要,能夠保留原始的 TIMESTAMP 值,而不是浪費空間的重複數據。參考 Partition Key Columns 瞭解關於日期和時間值的分區的詳細信息。
例子:
select cast('1966-07-30' as timestamp);
select cast('1985-09-25 17:45:30.005' as timestamp);
select cast('08:30:00' as timestamp);
select hour('1970-01-01 15:30:00'); -- Succeeds, returns 15.
select hour('1970-01-01 15:30'); -- Returns NULL because seconds field required.
select hour('1970-01-01 27:30:00'); -- Returns NULL because hour value out of range.
select dayofweek('2004-06-13'); -- Returns 1, representing Sunday.
select dayname('2004-06-13'); -- Returns 'Sunday'.
select date_add('2004-06-13', 365); -- Returns 2005-06-13 with zeros for hh:mm:ss fields.
select day('2004-06-13'); -- Returns 13.
select datediff('1989-12-31','1984-09-01'); -- How many days between these 2 dates?
select now(); -- Returns current date and time in UTC timezone.
create table dates_and_times (t timestamp);
insert into dates_and_times values
('1966-07-30'), ('1985-09-25 17:45:30.005'), ('08:30:00'), (now());
Related information: 不一樣格式日期類型之間的轉換、或執行日期計算,使用 Date and Time Functions 中描述的時間日期函數。
TINYINT 數據類型
1字節整數類型,用於 CREATE TABLE 和 ALTER TABLE 語句。
Range: -128 .. 127. 不是無符號子類型
Conversions: Impala自動轉換爲更大的整數類型 (SMALLINT, INT, BIGINT) 或浮點數類型 (FLOAT , DOUBLE) 。轉換爲 STRING 或 TIMESTAMP 須要使用 CAST() 函數。轉換整數值 N 爲 TIMESTAMP 時,是根據 Unix 紀元(January 1, 1970)開始的 N 秒來轉換。
Related information: INT Data Type, BIGINT Data Type, SMALLINT Data Type, Mathematical Functions
UNION 子句
使用 UNION 子句容許你組合多個查詢的結果集。默認的,組合結果集就相似於應用 DISTINCT 操做符。
Syntax:
query_1 UNION [DISTINCT | ALL] query_2
Usage notes:
僅使用 UNION 關鍵字與使用 UNION DISTINCT 相同。由於對於大的結果集消除重複是內存密集操做,全部儘量使用 UNION ALL(也就是說,當你知道 union 操做中不一樣的查詢將不產生任何重複,或者重複值能夠接受)。
當對 UNION ALL 或 UNION 查詢執行 ORDER BY 操做,一般同時須要 LIMIT 子句。假如你設置了 DEFAULT_ORDER_BY_LIMIT 查詢選項, 對整個結果集應用 ORDER BY 和 LIMIT 子句,那麼把 UNION 查詢放到子查詢裏,SELECT from 子查詢,並把 ORDER BY 子句放在子查詢的外面的最末尾。
Examples:
首先,咱們準備一些例子數據,包括重複的 1 的值。
[localhost:21000] > create table few_ints (x int);
[localhost:21000] > insert into few_ints values (1), (1), (2), (3);
[localhost:21000] > set default_order_by_limit=1000;
本例中演示了返回兩個查詢的全部結果的 UNION ALL 操做,沒有其餘的過濾器以消除重複。對於 Impala 一般查詢的大結果集,這是最節省內存的技術。
[localhost:21000] > select x from few_ints order by x;
+---+
| x |
+---+
| 1 |
| 1 |
| 2 |
| 3 |
+---+
Returned 4 row(s) in 0.41s
[localhost:21000] > select x from few_ints union all select x from few_ints;
+---+
| x |
+---+
| 1 |
| 1 |
| 2 |
| 3 |
| 1 |
| 1 |
| 2 |
| 3 |
+---+
Returned 8 row(s) in 0.42s
[localhost:21000] > select * from (select x from few_ints union all select x from few_ints) as t1 order by x;
+---+
| x |
+---+
| 1 |
| 1 |
| 1 |
| 1 |
| 2 |
| 2 |
| 3 |
| 3 |
+---+
Returned 8 row(s) in 0.53s
[localhost:21000] > select x from few_ints union all select 10;
+----+
| x |
+----+
| 10 |
| 1 |
| 1 |
| 2 |
| 3 |
+----+
Returned 5 row(s) in 0.38s
本例子演示了不包含 ALL 關鍵字的 UNION 子句,它壓縮告終果集消除了重複值,使得查詢花費更多的時間和更多的內存。這一額外的處理使得對於會返回成千上萬行的記錄的查詢這一技術不被推薦。
[localhost:21000] > select x from few_ints union select x+1 from few_ints;
+---+
| x |
+---+
| 3 |
| 4 |
| 1 |
| 2 |
+---+
Returned 4 row(s) in 0.51s
[localhost:21000] > select x from few_ints union select 10;
+----+
| x |
+----+
| 2 |
| 10 |
| 1 |
| 3 |
+----+
Returned 4 row(s) in 0.49s
[localhost:21000] > select * from (select x from few_ints union select x from few_ints) as t1 order by x;
+---+
| x |
+---+
| 1 |
| 2 |
| 3 |
+---+
Returned 3 row(s) in 0.53s
USE 語句
默認的,一開始鏈接到 Impala 實例的時候,你連入的是 default 數據庫。在 impala-shell 會話中執行 USE db_name 語句切換到其它數據庫。當你在表名前不使用數據庫名前綴,任意的 CREATE TABLE, INSERT, SELECT,或其餘語句都在當前數據庫運行(The current database is where any CREATE TABLE, INSERT, SELECT, or other statements act when you specify a table without prefixing it with a database name)。
Usage notes:
如下狀況下應切換默認數據庫:
在啓動 impala-shell 時設置 -d db_name 選項,爲特定數據庫自動執行 USE 語句。這一選項對運行 SQL 腳本有用,例如沒有硬編碼到 SQL 源碼中的針對多個數據庫的安裝或測試腳本。
Examples:
參見 CREATE DATABASE Statement 中包括 CREATE DATABASE, USE, DROP DATABASE 的例子
VALUES 子句
VALUES 子句是通用的設置單行或多行的全部列的方式。一般在 INSERT 語句中使用 VALUES 子句爲添加到表的單行或多行設置全部列值。
Note: INSERT ... VALUES 技術不適合載入大量的數據到基於 HDFS (HDFS-based)的表,由於插入操做沒法並行,而且每個語句產生單獨的數據文件。用於創建小尺寸的表(small dimension tables)或少許數據用於測試 SQL 語法或 HBase 表。不要用於大的 ETL做業或載入操做的基準測試。不要運行包含每次只插入單行數據的 數以千計的 INSERT ... VALUES 語句的腳本。假如在 ETL 操做中會產生不少小文件,那麼運行一個在一個 VALUES 子句中包含儘量多行數據的 INSERT .. VALUES 操做載入數據到一個臨時表,做爲整個 ETL 管道的一部分,並使用單獨的數據方便清理 (If you do run INSERT ... VALUES operations to load data into a staging table as one stage in an ETL pipeline, include multiple row values if possible within each VALUES clause, and use a separate database to make cleanup easier if the operation does produce many tiny files)
下面的例子演示了:
[localhost:21000] > describe val_example;
Query: describe val_example
Query finished, fetching results ...
+-------+---------+---------+
| name | type | comment |
+-------+---------+---------+
| id | int | |
| col_1 | boolean | |
| col_2 | double | |
+-------+---------+---------+
[localhost:21000] > insert into val_example values (1,true,100.0);
Inserted 1 rows in 0.30s
[localhost:21000] > select * from val_example;
+----+-------+-------+
| id | col_1 | col_2 |
+----+-------+-------+
| 1 | true | 100 |
+----+-------+-------+
[localhost:21000] > insert overwrite val_example values (10,false,pow(2,5)), (50,true,10/3);
Inserted 2 rows in 0.16s
[localhost:21000] > select * from val_example;
+----+-------+-------------------+
| id | col_1 | col_2 |
+----+-------+-------------------+
| 10 | false | 32 |
| 50 | true | 3.333333333333333 |
+----+-------+-------------------+
當在 INSERT 語句中使用時,Impala 中的 VALUES 子句不支持設置表的列的子集或使用不一樣的順序。使用 VALUES 子句時應以與表中定義相同的順序設置全部的列賦值,其中想要忽略的值使用 NULL 賦值。
就像在其餘語句中的表同樣, 使用括號括起 VALUES 子句並用 AS 子句爲整個對象和其中須要引用的列指定別名:
[localhost:21000] > select * from (values(4,5,6),(7,8,9)) as t;
+---+---+---+
| 4 | 5 | 6 |
+---+---+---+
| 4 | 5 | 6 |
| 7 | 8 | 9 |
+---+---+---+
[localhost:21000] > select * from (values(1 as c1, true as c2, 'abc' as c3),(100,false,'xyz')) as t;
+-----+-------+-----+
| c1 | c2 | c3 |
+-----+-------+-----+
| 1 | true | abc |
| 100 | false | xyz |
+-----+-------+-----+
例如,你可能使用一個相似這些字面常量或函數返回值構造的小表,做爲涉及到鏈接或 UNION ALL 操做的長 SQL 語句的一部分。
Views
視圖是一個輕量級的邏輯結構,是查詢的別名。你能夠在查詢(SELECT 語句或 INSERT 語句中的 SELECT 部分)中一般使用一個表名的位置使用視圖名代替。
視圖可以:
這一技術讓你建立幾個或多或少不一樣粒度的相同查詢,在合適的時候在它們之間切換(This technique lets you build up several more or less granular variations of the same query, and switch between them when appropriate)。
配置視圖的相關 SQL 語句是 CREATE VIEW Statement, ALTER VIEW Statement, DROP VIEW Statement。你能夠在查詢數據時 (SELECT Statement) 和從一個表向另外一個表複製數據時(INSERT Statement)使用視圖。WITH 子句建立了一個旨在單個查詢中存在的內聯視圖(inline view)。
[localhost:21000] > create view trivial as select * from customer;
[localhost:21000] > create view some_columns as select c_first_name, c_last_name, c_login from customer;
[localhost:21000] > select * from some_columns limit 5;
Query finished, fetching results ...
+--------------+-------------+---------+
| c_first_name | c_last_name | c_login |
+--------------+-------------+---------+
| Javier | Lewis | |
| Amy | Moses | |
| Latisha | Hamilton | |
| Michael | White | |
| Robert | Moran | |
+--------------+-------------+---------+
[localhost:21000] > create view ordered_results as select * from some_columns order by c_last_name desc, c_first_name desc limit 1000;
[localhost:21000] > select * from ordered_results limit 5;
Query: select * from ordered_results limit 5
Query finished, fetching results ...
+--------------+-------------+---------+
| c_first_name | c_last_name | c_login |
+--------------+-------------+---------+
| Thomas | Zuniga | |
| Sarah | Zuniga | |
| Norma | Zuniga | |
| Lloyd | Zuniga | |
| Lisa | Zuniga | |
+--------------+-------------+---------+
Returned 5 row(s) in 0.48s
以前例子中 ORDERED_RESULTS 使用了降序,由於在例子 TPCD-H 數據中,有許多行的 C_FIRST_NAME 和 C_LAST_NAME 的值爲 NULL,使得名稱正序排列沒有用(making the lowest-ordered names unuseful in a sample query)
create view visitors_by_day as select day, count(distinct visitors) as howmany from web_traffic group by day;
create view busiest_days as select day, howmany from visitors_by_day order by howmany desc;
create view top_10_days as select day, howmany from busiest_days limit 10;
select * from top_10_days;
執行 DESCRIBE FORMATTED 語句查看視圖定義,將顯示原始 CREATE VIEW 語句中的查詢:
[localhost:21000] > create view v1 as select * from t1;
[localhost:21000] > describe formatted v1;
Query finished, fetching results ...
+------------------------------+------------------------------+----------------------+
| name | type | comment |
+------------------------------+------------------------------+----------------------+
| # col_name | data_type | comment |
| | NULL | NULL |
| x | int | None |
| y | int | None |
| s | string | None |
| | NULL | NULL |
| # Detailed Table Information | NULL | NULL |
| Database: | views | NULL |
| Owner: | cloudera | NULL |
| CreateTime: | Mon Jul 08 15:56:27 EDT 2013 | NULL |
| LastAccessTime: | UNKNOWN | NULL |
| Protect Mode: | None | NULL |
| Retention: | 0 | NULL |
| Table Type: | VIRTUAL_VIEW | NULL |
| Table Parameters: | NULL | NULL |
| | transient_lastDdlTime | 1373313387 |
| | NULL | NULL |
| # Storage Information | NULL | NULL |
| SerDe Library: | null | NULL |
| InputFormat: | null | NULL |
| OutputFormat: | null | NULL |
| Compressed: | No | NULL |
| Num Buckets: | 0 | NULL |
| Bucket Columns: | [] | NULL |
| Sort Columns: | [] | NULL |
| | NULL | NULL |
| # View Information | NULL | NULL | | View Original Text: | SELECT * FROM t1 | NULL |
| View Expanded Text: | SELECT * FROM t1 | NULL | +------------------------------+------------------------------+----------------------+
Returned 29 row(s) in 0.05s
限制:
WITH 子句
能夠添加到 SELECT 語句以前的子句,用於定義複雜的、在以後的 SELECT 中會屢次引用的表達式。與 CREATE VIEW 相似,除了在 WITH 子句中定義的的表名和列名在查詢完成後不會保存下來,而且不會實際使用的表或視圖的名稱衝突。也被稱爲 "子查詢分解(subquery factoring)"。
你可使用子查詢重寫查詢,就跟 WITH 子句同樣工做。WITH 子句的目的是:
Note:
Impala 中 WITH 子句不支持在 WITH 中遞歸查詢,其餘數據庫系統可能支持
Standards compliance: Introduced in SQL:1999.
Examples:
-- Define 2 subqueries that can be referenced from the body of a longer query.
with t1 as (select 1), t2 as (select 2) insert into tab select * from t1 union all select * from t2;
-- Define one subquery at the outer level, and another at the inner level as part of the
-- initial stage of the UNION ALL query.
with t1 as (select 1) (with t2 as (select 2) select * from t2) union all select * from t1;