Impala SQL 語言元素(翻譯)[轉載]

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 TypeSMALLINT Data TypeTINYINT Data TypeMathematical 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 支持你們熟悉的比較操做用於檢測相等、存在併爲列數據類型排序:

  • =, !=, <>
  • IS NULL, IS NOT NULL
  • <, <=, >, >=
  • BETWEEN lower_bound AND upper_bound
  • LIKEREGEXP (僅支持STRING)

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 StatementTable 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 函數

返回知足必定條件記錄的行數或非空行的行數的聚合函數:

  • COUNT(*) 統計包含 NULL 值的全部行數
  • COUNT(column_name) 只計算該列中值非空的行數
  • 能夠結合使用 COUNT 與 DISTINCT 在計算前消除重複值,並計算多個列組合的值

當查詢中包含 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 裏,數據庫是:

  • 邏輯結構,包含在本身命名空間下組合在一塊兒的相關的表(A logical construct for grouping together related tables within their own namespace)。你能夠每一個應用、一組相關的表或一輪實驗都使用單獨的數據庫(You might use a separate database for each application, set of related tables, or round of experimentation)
  • 物理結構,對應 HDFS 中的目錄樹(A physical construct represented by a directory tree in HDFS)。表(內部表),分區,和數據文件都在該目錄下分配。你能夠備份、計算空間使用狀況、或使用 DROP DATABASE 語句刪除它(目錄爲空時)

建立數據的語法以下:

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 子句指定的函數在函數處理的不一樣階段進行調用。

  • Initialize: 在 INIT_FN 子句中指定的函數完成初始化設置,例如初始化內部數據結果的成員變量。This function is often a stub for simple UDAs. 你能夠忽略這一子句則會執行一個默認(無操做)函數操做。
  • Update: 在 UPDATE_FN 子句中指定的函數會在原始結果集的每一行調用一次,也就是說,在執行 GROUP BY 子句以前被執行。 對於 GROUP BY 子句返回的每個不一樣的值,會調用一個單獨的函數實例(A separate instance of the function is called for each different value returned by the GROUP BY clause)。 The final argument passed to this function is a pointer, to which you write an updated value based on its original value and the value of the first argument.
  • Merge: 在 MERGE_FN 子句中指定的函數被調用任意次數,與不一樣節點或不一樣線程的 Impala 並行讀取和處理數據文件產生的中間結果有關。The final argument passed to this function is a pointer, to which you write an updated value based on its original value and the value of the first argument.
  • Finalize: 在 FINALIZE_FN 子句執行釋放以前的 UDF 申請的資源,例如釋放內存,關閉以前打開的文件句柄,諸如此類。This function is often a stub for simple UDAs. 你能夠忽略這一子句則會執行一個默認(無操做)函數操做。

假如你對每個相關的函數使用一致的命名約定,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.

使用注意:

  • 你可使用 C++ 或 JAVA 編寫 Impala UDF。對於 Impala 來講,C++ UDFs 是新的、推薦的格式,能夠利用本地代碼提供更高性能。Impala 和 Hive 都兼容基於 JAVA(Java-based) 的 UDFs,最適合重用現存的 Hive UDFs (Impala 能夠運行基於 Java 的 Hive UDFs 但不支持 Hive UDAs)
  • UDF 對應一個 .so 或 .jar 文件,存放在 HDFS 中,並由 CREATE FUNCTION 語句分發到每個 Impala 節點
  • 當 SQL 語句執行時,Impala 根據處理結果集中全部行的須要調用相關的代碼。全部的 UDF 被分爲是肯定的,也就是說,當傳入相同的參數值時老是返回相同的結果。當從以前的調用中結果值已知,Impala 可能跳過也可能不跳過 UDF 的某些調用。所以,不要依賴於 UDF 特定的調用次數,也不要基於一些外部因素如當前時間、隨機數函數或當 Impala 執行查詢過程當中值會發生變化的外部數據源而返回不一樣的結果(Impala calls the underlying code during SQL statement evaluation, as many times as needed to process all the rows from the result set. All UDFs are assumed to be deterministic, that is, to always return the same result when passed the same argument values. Impala might or might not skip some invocations of a UDF if the result value is already known from a previous call. Therefore, do not rely on the UDF being called a specific number of times, and do not return different result values based on some external factor such as the current time, a random number function, or an external data source that could be updated while an Impala query is in progress)
  • UDF 函數中的參數名不重要,重要的是它們的數量、位置和數據類型
  • 你能夠經過建立多版本的使用不一樣參數簽名的函數來重載相同的函數名,但基於安全的緣由,不容許建立與內部函數重名的 UDF 函數
  • 在 UDF 代碼裏,函數返回一個 struct。其中 struct 包含兩個字段.。第一個字段是 boolean 類型,表示返回值是否爲 NULL(當本字段返回 true 時,返回值被解釋爲 NULL)。第二個字段與函數的返回類型數據類型相同,當函數返回值不爲 NULL 時持有返回值
  • In the UDF code, you represent the function arguments as an initial pointer to a UDF context structure, followed by references to zero or more structs, corresponding to each of the arguments. Each struct has the same 2 fields as with the return value, a boolean field representing whether the argument is NULL, and a field of the appropriate type holding any non-NULL argument value.
  • 關於 UDF 的例子代碼和編譯說明,參考 Impala 提供的例子目錄
  • 由於 對於 UDF 函數主體的文件存放在 HDFS中,自動對全部的 Impala 節點可用。你不須要在服務器之間手工複製 UDF 相關文件
  • 由於 Impala 目前不支持 ALTER FUNCTION 語句,假如你須要重命名函數,移動到其餘數據庫,或者修改它的前面或其餘屬性,應先對原函數執行 DROP FUNCTION 語句進行刪除,而後執行以指望的屬性執行 CREATE FUNCTION 語句建立函數
  • 由於每個 UDF 與特定的數據庫相關,所以在執行任何 CREATE FUNCTION 語句以前,應先執行 USE 語句指定數據庫,或者使用 db_name.function_name 來指定數據庫

假如爲了負載均衡的緣由,在 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 語句可用以一下場景:

  • 將最長最複雜的 SQL 查詢轉換爲一行查詢,你能夠在應用中、腳本中、或 impala-shell 交互式查詢中執行鍼對視圖的簡單的查詢。例如:
    • select * from view_name;
    • select * from view_name order by c1 desc limit 10;
 

原始查詢越複雜越難以閱讀,使用視圖的簡單查詢越有效果。

  • 隱藏底層表和列,當這些發生變化時減小維護量。這時候,只須要用新的名稱重建視圖,全部查詢視圖而不是底層表的語句就能夠不須要修改就正常運行
  • 測試優化技術並把優化後的查詢提供給全部應用使用(To experiment with optimization techniques and make the optimized queries available to all applications)。例如.你發現了一個 WHERE 條件,鏈接順序,鏈接提示(join hints),等等組合中在一塊兒能得到最佳性能的一類查詢,你能夠創建一個使用這一最佳組合技術的視圖。應用能夠對視圖進行相對簡單的查詢,而不是重複着一遍又一遍的繁雜而優化的邏輯。如何以後發現了比原始查詢更好的優化方式,重建這個視圖,全部應用能夠馬上從中受益
  • 簡化整類的相關查詢,特別是在多個表執行鏈接,對列進行復雜計算、以及其餘語法致使整個查詢難以理解和調試查詢。例如你能夠建立一個視圖,鏈接幾個表,使用幾個 WHERE 條件過濾數據,並從結果集選擇幾列。應用能夠在這個視圖上上執行僅僅是 LIMIT, ORDER BY 等相似簡單子句上不一樣的查詢。

對於須要一遍遍重複的查詢的複雜子句,例如在查詢項, 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 的結果:

  • DESCRIBE 表或視圖會返回每個列的名稱、類型和備註。對於視圖,假如列值是表達式計算得來的,列名會自動根據列的序號生成如 _c0, _c1等等
  • 在建立時沒有特別指定格式或存儲子句的表被認爲是 MANAGED_TABLE (Impala 術語是 "內部表")。它的存放在 HDFS 目錄中的數據文件位於 Hive 數據目錄下。默認使用文本數據格式
  • 在 DESCRIBE FORMATTED 輸出中,視圖被視爲 VIRTUAL_VIEW。由於繼承自基本表,視圖的一些屬性爲 NULL 或空白。定義視圖的查詢語句是 DESCRIBE FORMATTED 輸出的一部分
  • 在 CREATE TABLE 語句中包含額外子句的表在 DESCRIBE FORMATTED 的輸出會有差別。表 T2 的輸出包括 EXTERNAL_TABLE 關鍵字,由於使用了 CREATE EXTERNAL TABLE 語法,而且不一樣的 InputFormat 和 OutputFormat 字段值以對應 Parquet 文件格式

[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 語句而數據問題沒有刪除,多是如下緣由:

  • 表是外部表(EXTERNAL), Impala 不改變全部文件和目錄。當數據是其餘 Hadoop 組件控制, Impala 只是從這些原始位置進行數據查詢時,應使用外部表
  • 若是對 impala 用戶 HDFS 回收站不可用,Impala 也會離開而不刪除數據文件(Impala might leave the data files behind unintentionally, if there is no HDFS location available to hold the HDFS trashcan for the impala user)。參見 User Account Requirements 瞭解如何配置所需的 HDFS 主目錄。

請使用 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)。

  • 能夠在 Impala 查詢表中的數據
  • 若是使用 HDFS 操做添加或替換數據,在 impala-shell 裏執行 REFRESH 命令以便 Impala 瞭解數據文件、塊位置等等的變化
  • 當在 Impala 中執行 DROP TABLE 語句時,Impala 會刪除關於這個文件的鏈接,但不會實際刪除對應的數據,你能夠繼續在其餘 Hadoop 組件和 HDFS 操做中使用這一數據文件

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 關鍵詞以後馬上緊跟如下結構之一:

  • [SHUFFLE] - 鏈接操做使用了"分割(partitioned)"技術,使用哈希算法分割兩個表對應的行,發送這些行的子集到其餘節點進行處理(關鍵字 SHUFFLE 用於表示 "分割鏈接(partitioned join)",由於這種鏈接與"分區表"無關)。 由於當表和索引統計信息不可用時,默認使用另外的"廣播(broadcast)"鏈接機制,你能夠在廣播鏈接不適用的狀況使用此提示;一般分割鏈接對具備類似大小的大表之間的鏈接更有效
  • [BROADCAST] - 使用"廣播(broadcast)"技術,把右邊(right-hand)表的完整內容發送到全部節點執行鏈接處理。這是表和索引統計信息不可用時的默認操做方式,因此你一般只須要在元數據失效致使 Impala 錯誤的選擇分割鏈接操做時才使用此提示。一般當其中一個表比另一個表小不少的時候更有效(把較小的表放在 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 目前支持:

  • INSERT INTO 語句向表中追加數據
  • INSERT OVERWRITE 語句替換表中數據
  • 使用 SELECT 查詢從其餘表複製數據。在 Impala 1.2.1 及以上版本,你能夠單獨使用 CREATE TABLE AS SELECT 語法做爲 CREATE TABLE 和 INSERT 語句的替代,它隱藏了實際的 INSERT 關鍵詞。
  • 能夠在 INSERT 以前使用可選的 WITH 子句,預先定義 SELECT 部分中使用的子查詢
  • 經過 VALUES 子句使用常數表達式來建立一行或多行新行(Create one or more new rows using constant expressions through VALUES clause) (Impala 1.0.1 中添加的 VALUES 子句)
  • 設置被插入列與 INSERT 語句中查詢的表的列不一樣的名稱或順序(Specify the names or order of columns to be inserted, different than the columns of the table being queried by the INSERT statement)(Impala 1.1 中添加)
  • 在 INSERT 關鍵字後緊跟一個可選的提示子句,用以微調插入到分區表時的行爲。提示關鍵詞是 [SHUFFLE] 和 [NOSHUFFLE],包括其中的方括號。默認是 [SHUFFLE]。此提示主要用於插入到 Parquet 分區表時。這是一個耗費資源的操做,由於可能會同時向 HDFS 寫入許多文件,併爲每個分區分配單獨的 1G 內存緩存(This can be a resource-intensive operation because it potentially involves many files being written to HDFS simultaneously, and separate 1GB memory buffers being allocated to buffer the data for each partition)

  Note:

  •  插入命令會致使 Hive 元數據的改變(Insert commands that partition or add files result in changes to Hive metadata)。由於 Impala 使用 Hive 元數據,這些變化須要刷新 Hive 元數據。更多信息參見 REFRESH 功能。
  • 目前 Impala 只支持插入數據到 TEXT 文件和 Parquet 文件格式的表。其餘格式的表,使用 Hive 插入數據後再使用 Impala 查詢

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 TypeBIGINT Data TypeSMALLINT Data TypeTINYINT Data TypeMathematical Functions

內部表

CREATE TABLE 語句默認生成的表是內部表(internal table)。(與之對應的是外部表,由 CREATE EXTERNAL TABLE 語句生成)

  • Impala 在 HDFS 中建立一個目錄存放數據文件
  • 經過在 impala-shell 執行 INSERT 語句或在 Hive 中運行 LOAD DATA 語句來載入數據
  • 當執行 DROP TABLE 語句時,Impala 物理刪除該目錄下的數據文件

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 實例的元數據:

  • 發生了元數據變化
  • 而且 是集羣中其餘 impalad 實例或 Hive 致使的變化
  • 而且 是 Impala shell 或 ODBC 客戶端直接鏈接的數據庫產生的變化( and the change is made to a database to which clients such as the Impala shell or ODBC directly connect)

當你在執行了 ALTER TABLE,INSERT 或其餘的表修改語句的相同的 Impala 節點執行查詢時  須要更新元數據。

數據庫和表的元數據一般由下列語句修改:

  • Hive - 經過 ALTER, CREATE, DROP , INSERT 操做
  • Impalad - 經過 CREATE TABLE, ALTER TABLE, INSERT 操做

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)。一般如下狀況使用鏈接查詢:

  • 當相關的數據從不一樣的源得到,每個數據集物理存放在單獨的表裏。例如,你可能從業務記錄中有地址數據,與電話列表或戶籍數據進行交叉校驗(When related data arrives from different sources, with each data set physically residing in a separate table. For example, you might have address data from business records that you cross-check against phone listings or census data)

  Note: Impala 能夠鏈接不一樣文件格式的表,包括 Impala 管理表和 HBase 表。例如,你可能在 Hbase 表中保持小的維度表,以便單行查找和更新,使用 Parquet 或其餘針對掃描操做優化的二進制文件格式保存大的事實表。這樣,你能夠執行一個交叉引用維表和事實表的 鏈接查詢。

  • 在數據標準化中,一項技術減小數據冗餘的技術就是拆分到多個表裏(When data is normalized, a technique for reducing data duplication by dividing it across multiple tables)。這種組織常見於傳到關係數據庫系統的數據,例如,不是在每一個表中都重複存放一個長字符串,好比客戶名,而是每個表中都包含一個數字的客戶ID。須要顯示客戶名稱的查詢能夠"鏈接"表指定客戶ID對應的名稱
  • 當某些列不多須要查詢時,能夠把它移動到單獨的表中以減小經常使用查詢的開銷。例如對僱員數據的查詢不多會須要 biography 字段。把它放到單獨的表裏會減小經常使用的查找僱員地址和電話時的 I/O 數量。須要 biography 列的查詢能夠經過鏈接它所在的單獨的表來實現。

  Note:

鏈接查詢的性能是 Impala 的重要方面,由於複雜的鏈接查詢是資源密集操做。一個有效的鏈接查詢比低效的鏈接查詢產生低得多的網絡傳輸和 CPU 負載。爲了最佳結果:

  • 確保查詢中涉及到的全部的表的表和列的統計信息可用,特別是任意鏈接條件中涉及的列。使用 SHOW TABLE STATS table_name 和 SHOW COLUMN STATS table_name 檢查
  • 若是表和列的統計信息不可用,先鏈接最大的表。你能夠經過 SHOW TABLE STATS table_name 和 SHOW COLUMN STATS table_name 語句檢查統計信息是否存在。在 Impala 1.2.2 及以上版本,使用 COMPUTE STATS 語句在表和列一級採集統計信息,在任何實質性的插入和載入數據操做以後保證統計信息最新
  • 若是表和列的統計信息不可用,基於整體大小和 WHERE 子句,選擇最有選擇性過濾前的表做爲隨後鏈接的表。鏈接具備最有選擇性過濾器的表返回最少數量的行(If table or column statistics are not available, join subsequent tables according to which table has the most selective filter, based on overall size and WHERE clauses. Joining the table with the most selective filter results in the fewest number of rows being returned)

關於鏈接查詢性能的更多信息和例子,參見 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 子句設置結果集中的最大行數。在如下場景有用:

  • 返回一個 top-N 查詢的肯定的前 N 項,such as the 10 highest-rated items in a shopping category or the 50 hostnames that refer the most traffic to a web site.
  • 演示表或特定查詢的一些樣本值,其中查詢沒有使用 ORDER BY 子句
  • 當表大於預期,或 WHERE 子句匹配的行數超出預期而致使海量結果集時,保證查詢正常(To keep queries from returning huge result sets by accident if a table is larger than expected, or a WHERE clause matches more rows than expected)

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 數據目錄
  • 你能夠指定被移動的單個數據文件 HDFS 路徑,或要移動的全部文件所在的目錄。可是不能使用任何形式的通配符只移動目錄中的部分文件。當加載一個目錄下的全部數據文件時,請確保全部的數據文件都在頂層目錄下,沒有在其中的嵌套目錄裏
  • 目前 Impala LOAD DATA 語句只能從 HDFS 中加載,不能從本地文件系統中加載。不支持 Hive LOAD DATA 語句的 LOCAL 關鍵字。必須指定路徑而不能使用 hdfs:// URI
  • 基於速度方面的考慮,只對有限的錯誤進行檢查(In the interest of speed, only limited error checking is done)。加入加載的文件具備錯誤的文件格式,與目標表不一樣的列,或其餘的類型不匹配, Impala 不會爲 LOAD DATA 語句引起錯誤。以後查詢該表可能產生運行時錯誤或意外的結果。目前,LOAD DATA 語句檢查所作的只是避免未壓縮文本文件和 LZO 壓縮文本文件在同一個表中混合在一塊兒
  • 當你在 LOAD DATA 參數中指定了 HDFS 目錄名,目錄下的任何隱藏文件 (以 . 開頭的文件名) 都不會移動到 Impala 數據目錄中
  • 加載的數據文件在新位置保留原有的名稱,除非與現存的數據文件名稱衝突,這時候會對新文件名略加修改爲爲惟一的名稱(重名文件的處理與 Hive LOAD 語句略有不一樣,Hive 中是替換重名的文件(The name-mangling is a slight difference from the Hive LOAD DATA statement, which replaces identically named files))
  • 經過提供一種簡單的方法從已知的 HDFS 位置傳輸文件到 Impala 數據目錄結構,LOAD DATA 語句可讓你避免記憶包含 Impala 數據庫和表的 HDFS 目錄樹的位置與佈局(使用  DESCRIBE FORMATTED table_name 語句,做爲一種快速檢查 Impala 表的數據文件位置的方法)
  • 對於提取分區表的新數據使用 PARTITION 子句特別方便。當你收到一個時間段、地理區域、或其餘對應着一個或多個分區列的部分數據時,你能夠直接加載這些數據到對應的 Impala 數據目錄,若是表有多個分區列,那麼可能目錄下有多層嵌套目錄。當表被分區時,你必須爲全部的分區列指定常量值(When the table is partitioned, you must specify constant values for all the partitioning columns)

假如爲了負載均衡的緣由,在 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)數據,修正這一數據對於大數據集至關耗時。

  • NULL 與空字符串的值不一樣。空字符串表現爲裏面沒有字符的字符串,"" 或 ''.
  • 在一個字符分隔文本文件裏,NULL 值使用特殊標記 \N 表示
  • 當 Impala 插入數據到分區表,而且其中一個分區列爲 NULL 或空字符串時,數據被放置到保存這兩種值的特定分區。當這些值在查詢中返回時,不管原始值爲 NULL 或空字符串,返回值都是  NULL 。這一行爲是爲了與 Hive 中處理分區表中的 NULL 值的作法兼容。 Hive 不容許空字符串做爲分區鍵,並在查詢中返回 NULL 值的時候返回一個字符串值如 __HIVE_DEFAULT_PARTITION__ 而不是 NULL。例如:
    • create table t1 (i int) partitioned by (x int, y string);
    • -- Select an INT column from another table, with all rows going into a special HDFS subdirectory
    • -- named __HIVE_DEFAULT_PARTITION__. Depending on whether one or both of the partitioning keys
    • -- are null, this special directory name occurs at different levels of the physical data directory
    • -- for the table.
    • insert into t1 partition(x=NULL, y=NULL) select c1 from some_other_table;
    • insert into t1 partition(x, y=NULL) select c1, c2 from some_other_table;
    • insert into t1 partition(x=NULL, y) select c1, c3  from some_other_table;
  • 當定義列的時候,不支持 NOT NULL 子句來限制列中不容許 NULL 值(There is no NOT NULL clause when defining a column to prevent NULL values in that column)
  • 不支持 DEFAULT 子句指定非空列的默認值
  • 如何 INSERT 操做中只提到了一部分列,則沒有提到的列在全部插入的行中都爲 NULL 
  • 在 Impala 1.2.1 及以上版本,全部的 NULL 值會列在 ORDER BY ... ASC 查詢結果集的末尾,列在 ORDER BY ... DESC 查詢的結果集的開頭。事實上, NULL 被認爲大於排序中其餘的全部值。以前的 Impala 老是把 NULL 值放到最後,即便是 ORDER BY ... DESC 查詢。Impala 1.2.1 中的最新行爲使得與其餘在通用數據庫系統更兼容。在 Impala 1.2.1 及以上版本,你能夠在 ORDER BY 子句的末尾添加 NULLS FIRST 或 NULLS LAST 子句來覆蓋或指定 NULL 的排序行爲。
 

  Note: 由於在當前 Hive 查詢中 NULLS FIRST 和 NULLS LAST 關鍵字不可用,你使用這些關鍵字建立的視圖在 Hive 中都不可用

  • 除了 ORDER BY 排序中的比較之外,全部與 NULL 的比較都會返回 NULL,使得比較毫無心義。例如, 10 > NULL 返回 NULL, 10 < NULL 一樣返回 NULL, 5 BETWEEN 1 AND NULL 同樣返回 NULL

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):

  • 當爲表加載新的數據文件到 HDFS 數據目錄後 (一旦你設置了按期加載數據到 Impala 中的 ETL 管道操做,這一般是最多見的須要刷新元數據的緣由)
  • 當在 Hive 中執行了 ALTER TABLE, INSERT, LOAD DATA, 或其餘修改表的 SQL 語句以後

你只須要在你鏈接並執行查詢的節點執行 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 實例的元數據:

  • 發生了元數據變化
  • 而且 是 Hive 致使的變化
  • 而且 是 Impala shell 或 ODBC 客戶端直接鏈接的數據庫產生的變化(the change is made to a database to which clients such as the Impala shell or ODBC directly connect)

當你在 Impala 而不是 Hive 中執行了 ALTER TABLE,INSERT 或其餘的表修改語句的時候  須要更新元數據。

數據庫和表的元數據一般由如下語句修改:

  • Hive - 經過 ALTER, CREATE, DROP , INSERT 操做
  • Impalad - 經過 CREATE TABLE, ALTER TABLE, INSERT 操做。在 Impala 1.2 及以上版本,這些變化被 Impala 目錄服務傳播給全部 Impala 節點

使用 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 查詢支持:

  • SQL 數據類型: booleantinyintsmallintintbigintfloatdoubletimestampstring.
  • 在 SELECT 關鍵字以前的一個可選的 WITH 子句,用於定義一個子查詢,子查詢和其中的的列名能夠在以後的主查詢中引用
  • 每個查詢的 DISTINCT 子句,參考 DISTINCT Operator 瞭解詳細信息
  • FROM 子句中的子查詢
  • WHERE, GROUP BY, HAVING 子句
  • ORDER BY 子句。Impala 要求同時使用 LIMIT 子句

  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

  • JOIN 子句。支持 Left, right, semi, full, 和 outer joins。Impala 1.2.2 添加 CROSS JOIN 操做。參見 Joins 瞭解詳細信息。 你能夠在 SELECT 關鍵字以後緊跟 STRAIGHT_JOIN 關鍵字,用來覆蓋 Impala 內部處理 join 子句時表載入的順序(You can also include the keyword STRAIGHT_JOINimmediately after the SELECT keyword to override the reordering of join clauses that Impala does internally.)
  • UNION ALL
  • LIMIT
  • 外部表
  • 關係操做如大於\小於或等於
  • 算術運算符如加法或減法
  • 邏輯/布爾操做 AND, OR, NOT。Impala 不支持對應的符合 &&, ||, !.
  • 普通的 SQL 內置函數如 COUNT, SUM, CAST, LIKE, IN, BETWEEN, COALESCE。 Impala 支持的內置函數見 Built-in Function Support.
  • 使用 WITH 子句來抽象重複的,如聚合函數,會在相同的查詢中屢次引用的子句(WITH 子句實際在 SELECT 語句以前執行)

SHOW 語句

SHOW 子句是一種靈活的獲取 Impala 中不一樣種類對象信息的方式。你能夠運行 SHOW object_type 語句來查看當前數據庫中對應的對象,或運行 SHOW object_type IN database_name 來查看特定數據庫中的對象。

執行如下語句,顯示特定種類全部可用對象的列表:

  • SHOW DATABASES
  • SHOW SCHEMAS - SHOW DATABASES 的別名
  • SHOW TABLES [IN database_name]
  • SHOW FUNCTIONS [IN database_name]
  • SHOW CREATE TABLE [database_name].table_name
  • SHOW TABLE STATS [database_name.]table_name. 參見 Table Statistics 瞭解使用注意事項和例子
  • SHOW COLUMN STATS [database_name.]table_name. 參見 Column Statistics 瞭解使用注意事項和例子

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 TypeBIGINT Data TypeTINYINT Data TypeINT Data TypeMathematical 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)的字符串數據,請在客戶端實現此邏輯。

轉換:

  • Impala 不會自動把 STRING 轉換爲任意其餘類型
  • 可使用 CAST() 函數,轉換 STRING 爲 TINYINT, SMALLINT, INT, BIGINT, FLOAT, DOUBLE, TIMESTAMP
  • 能夠直接把 STRING 轉換爲 BOOLEAN。可使用 CASE 表達式計算字符串的值如 'T', 'true', 等等,並返回對應的 Boolean 類型的 true 和 false
  • 能夠把 BOOLEAN 值轉換爲 STRING,true 返回 '1',false 返回 '0'

Related information: String FunctionsDate 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 TypeBIGINT Data TypeSMALLINT Data TypeMathematical 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:

如下狀況下應切換默認數據庫:

  • 避免在帶數據庫名前綴訪問引用的表。例如, SELECT * FROM t1 JOIN t2 而不是 SELECT * FROM db.t1 JOIN db.t2.
  • 在同一個數據庫中做一系列操做,如建立表、插入數據、並查詢表

在啓動 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)

下面的例子演示了:

  • 如何使用 VALUES 子句插入單行記錄
  • 如何使用 VALUES 子句插入多行記錄
  • 如何使用 VALUES 子句經過 INSERT INTO 追加單行或多行數據到表中,或者經過 INSERT OVERWRITE 替換現有表的內容
  • VALUES 子句中的條目能夠是常量(literals)、函數值、或其餘表達式

[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 部分)中一般使用一個表名的位置使用視圖名代替。

視圖可以:

  • 創建細粒度的(fine-grained)安全,用戶能夠查詢表中的一部分列而沒法查詢其餘的列。參見 Controlling Access at the Column Level through Views 瞭解詳細信息
  • 以緊湊而簡單的語法執行復雜查詢:
    • -- 建立一個複雜的報表查詢,將其加入到 CREATE VIEW 語句...
    • create view v1 as select c1, c2, avg(c3) from t1 group by c3 order by c1 desc limit 10;
    • -- ... 如今你能夠只用 1 行代碼生成報表
    • select * from v1;
  • 經過避免在多種語言的多個應用中重複使用的複雜查詢來減小維護量
    • create view v2 as select t1.c1, t1.c2, t2.c3 from t1 join t2 on (t1.id = t2.id);
    • -- 下面簡單的查詢比上面複雜的查詢嵌入到報表應用安全
    • -- 即便底層表結構變化了,視圖的定義仍能夠保持穩定
    • select c1, c2, c3 from v2;
  • 在原始查詢之上,添加新的子句、select-list 表達式、函數調用、等等,創建一個新的、更精緻的查詢:
    • create view average_price_by_category as select category, avg(price) as avg_price from products group by category;
    • create view expensive_categories as select category, avg_price from average_price_by_category order by avg_price desc limit 10000;
    • create view top_10_expensive_categories as select category, avg_price from expensive_categories limit 10;
 
 
 

這一技術讓你建立幾個或多或少不一樣粒度的相同查詢,在合適的時候在它們之間切換(This technique lets you build up several more or less granular variations of the same query, and switch between them when appropriate)。

  • 爲表、列、鏈接的結果集等等設置直觀的別名:
    • -- 原始表可能有從歷史系統集成下來的神祕名稱(The original tables might have cryptic names inherited from a legacy system)
    • create view action_items as select rrptsk as assignee, treq as due_date, dmisc as notes from vxy_t1_br;
    • -- 你能夠爲了兼容性保留原有名稱,而使用更直觀的名稱創建新應用
    • select assignee, due_date, notes from action_items;
  • 與其餘使用不一樣文件格式、分區方案、等等,不須要數據複製或轉換的停機時間的交換表:
    • create table slow (x int, s string) stored as textfile;
    • create view report as select s from slow where x between 20 and 30;
    • -- 由於低效的表定義,查詢緩慢,可是正常工做(Query is kind of slow due to inefficient table definition, but it works)
    • select * from report;
    •  
    • create table fast (s string) partitioned by (x int) stored as parquet;
    • -- ...從 SLOW 複製數據到 FAST。針對 REPORT 視圖的查詢繼續工做...
    •  
    • -- 修改視圖定義以後,由於新表採用分區、二進制文件格式、壓縮,查詢會變快
    • alter view report as select s from fast where x between 20 and 30;
    • select * from report;
  • 避免編寫冗長的子查詢和在許多查詢中使用的相同子查詢
 
 

配置視圖的相關 SQL 語句是 CREATE VIEW StatementALTER VIEW StatementDROP 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

限制:

  • Impala 中沒法想視圖中插入數據(在一些數據庫系統中,支持這一操做並向基礎表中插入數據)。你能夠在 INSERT 語句的 右側 SELECT 部分使用視圖
  • 假如視圖是基於分區表的,任意分區的修剪經過原始查詢中子句決定。假如視圖上的查詢包含額外的引用了分區鍵列的 WHERE 子句,Impala 不會自動修剪添加的列(If a view applies to a partitioned table, any partition pruning is determined by the clauses in the original query. Impala does not prune additional columns if the query on the view includes extra WHERE clauses referencing the partition key columns)

WITH 子句

能夠添加到 SELECT 語句以前的子句,用於定義複雜的、在以後的 SELECT 中會屢次引用的表達式。與 CREATE VIEW 相似,除了在 WITH 子句中定義的的表名和列名在查詢完成後不會保存下來,而且不會實際使用的表或視圖的名稱衝突。也被稱爲 "子查詢分解(subquery factoring)"。

你可使用子查詢重寫查詢,就跟 WITH 子句同樣工做。WITH 子句的目的是:

  • 查詢中更少重複,更方便和易於維護。一般用於涉及 UNION, joins,聚合函數、相似的複雜表達式屢次被引用的查詢(Typically used with queries involving UNION, joins, or aggregation functions where the similar complicated expressions are referenced multiple times.)
  • 經過抽出查詢中最複雜的部分做爲單獨的一塊,SQL 代碼更容易閱讀和理解
  • 提升與支持這一語句的其餘數據庫系統的兼容性(主要是 Oracle 數據庫)

  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;

相關文章
相關標籤/搜索