摘要: http://www.cloudera.com/content/cloudera-content/cloudera-docs/Impala/latest/Installing-and-Using-Impala/ciiu_langref_sql.html Impala SQL 語言元素(Ele ...
摘要: http://www.cloudera.com/content/cloudera-content/cloudera-docs/Impala/latest/Installing-and-Using-Impala/ciiu_langref_sql.html
Impala SQL 語言元素(Elements)
Impala SQL 方言支持一組標準元素(a range of standard elements),加上許多大數據方面的擴展,用於數據載入和數據倉庫方面。
註意:在之前的 Impala beta 版中,在 impala-shell 中每一語句結束時的分號是可選的。現在 impala-shell 支持多行命令,以便於從腳本文件中複製粘貼代碼,這樣每一語句結束時的分號是必需的。
下麵章節演示了 Impala 中 SQL 語言的主要語句、子句以及其他元素。
繼續閱讀:
- ALTER TABLE Statement
- ALTER VIEW Statement
- AVG Function
- BETWEEN Operator
- BIGINT Data Type
- BOOLEAN Data Type
- Comments
- Comparison Operators
- COMPUTE STATS Statement
- COUNT Function
- CREATE DATABASE Statement
- CREATE FUNCTION Statement
- CREATE TABLE Statement
- CREATE VIEW Statement
- DESCRIBE Statement
- DISTINCT Operator
- DOUBLE Data Type
- DROP DATABASE Statement
- DROP FUNCTION Statement
- DROP TABLE Statement
- DROP VIEW Statement
- EXPLAIN Statement
- External Tables
- FLOAT Data Type
- GROUP BY Clause
- HAVING Clause
- Hints
- INSERT Statement
- INT Data Type
- Internal Tables
- INVALIDATE METADATA Statement
- Joins
- LIKE Operator
- LIMIT Clause
- LOAD DATA Statement
- MAX Function
- MIN Function
- NDV Function
- NULL
- OFFSET Clause
- ORDER BY Clause
- REFRESH Statement
- REGEXP Operator
- RLIKE Operator
- SELECT Statement
- SHOW Statement
- SMALLINT Data Type
- STRING Data Type
- SUM Function
- TIMESTAMP Data Type
- TINYINT Data Type
- UNION Clause
- USE Statement
- VALUES Clause
- Views
- WITH Clause
ALTER TABLE 語句
ALTER TABLE 語句用來修改現有表的結構或屬性。在 Impala 里,這是一個邏輯操作,更新了 Impala 和 Hive 共用的 metastore 資料庫中表的元數據; ALTER TABLE 語句不會對實際的數據文件進行重寫、移動等操作。因此,你可能需要相應的物理文件系統操作才能實現移動數據文件到不同的 HDFS 目錄,重寫數據文件來包含其他欄位,或轉換成不同的文件格式。
重命名錶:
ALTER TABLE old_name RENAME TO new_name;
對於內部表,這一操作實際地修改了包含數據文件的 HDFS 目錄名;原始目錄將不再存在。通過修改表名前面的資料庫名,你可以把一個資料庫中的內部表(包括對應的數據目錄)移動到另一個資料庫。例如:
create database d1; create database d2; create database d3; use d1; create table mobile (x int); use d2; -- 移動其他資料庫中的表到當前資料庫 alter table d1.mobile rename to mobile; use d1; -- 移動一個資料庫中的表達哦另一個資料庫 alter table d2.mobile rename to d3.mobile;
修改 Impala 查找表的相關數據文件的物理位置:
ALTER TABLE table_name SET LOCATION 'hdfs_path_of_directory';
指定的路徑是數據文件所在的完整路徑,或者是不存在被創建的路徑。Impala 不會創建該表名下麵的額外子目錄。Impala 不會移動任意數據文件到新位置,也不會修改這一目錄下現存的數據文件。
修改 TBLPROPERTIES 和 SERDEPROPERTIES 列的鍵值對:
ALTER TABLE table_name SET TBLPROPERTIES ('key1'='value1', 'key2'='value2', ...); ALTER TABLE table_name SET SERDEPROPERTIES ('key1'='value1', 'key2'='value2', ...);
TBLPROPERTIES 子句是將任意用戶指定數據項與特定表關聯起來的主要方法(The TBLPROPERTIES clause is primarily a way to associate arbitrary user-specified data items with a particular table)。SERDEPROPERTIES 子句設置表如何讀寫,在 Hive 中許多情況下需要,實際在 Impala 中未使用(The SERDEPROPERTIES clause sets up metadata defining how tables are read or written, needed in some cases by Hive but not actually used by Impala)。參考 CREATE TABLE Statement 瞭解這些子句的詳細信息。參考 Setting Statistics Manually through ALTER TABLE 中的使用表屬性來微調相關表統計信息的性能的例子(for an example of using table properties to fine-tune the performance-related table statistics)。
重組表中的列:
ALTER TABLE table_name ADD COLUMNS (column_defs); ALTER TABLE table_name REPLACE COLUMNS (column_defs); ALTER TABLE table_name CHANGE column_name new_name new_spec; ALTER TABLE table_name DROP column_name;
其中 column_spec 與 CREATE TABLE 語句中相同:列名,列數據類型,以及可選的列備註。你可以一次添加多個列。無論是添加單個列還是多個列,都需要用括弧括起來。當替換列時,原有列的定義都被廢棄。你可能會在收到一組新的有不同數據類型或不同順序的列的數據文件時使用這一技術(數據文件會被保留,因此當新列與舊列不相容時,需要在執行進一步的查詢前,使用 INSERT OVERWRITE 或 LOAD DATA OVERWRITE 語句替換所有的數據)。
你可以使用 CHANGE 子句重命名某一個列,或轉換現存的列為其他類型,例如在 STRING 和 TIMESTAMP 之間轉換,或者在 INT 與 BIGINT 之間轉換。一次只能刪除一個列;想要刪除多個列,需要執行多次 ALTER TABLE 語句,或者在單個 ALTER TABLE ... REPLACE COLUMNS 語句中定義一組新的列。
修改 Impala 中表期望的文件格式(To change the file format that Impala expects table data to be in):
ALTER TABLE table_name SET FILEFORMAT { PARQUET | PARQUETFILE | TEXTFILE | RCFILE | SEQUENCEFILE }
因為本操作只是修改表的元數據,對現存的數據,你必須使用 Impala 之外的 Hadoop 技術對已有的數據進行轉換。之後再在 Impala 中使用 INSERT 語句創建的數據將使用新的格式。你不能指定文本文件的分隔符;文本文件的分隔符必須是逗號。
為了添加或刪除表的分區, 表必須已經是分區表(也就是說,使用帶 PARTITIONED BY 子句創建的表)。分區是一個 HDFS 中的實際目錄,目錄名包含特定列的值(partition key,分區鍵)。假如必要,Impala 的 INSERT 語句會創建分區,因此 ALTER TABLE ... ADD PARTITION 語句的主要用途是通過移動或複製已有的數據文件到分區對應的 HDFS 目錄來導入數據。DROP PARTITION 子句用於刪除一組指定分區鍵值對應的 HDFS 目錄和對應的數據文件;例如,假如你總是分析最近 3 個月數據的價值,在每個月初你就可以刪除掉不再需要的最老的那個分區的數據。刪除分區會減少表相關的元數據數量,減輕計算查詢計劃的複雜度,從而可以簡化和提升分區表的查詢速度,特別是連接查詢。下麵展示了 ADD PARTITION 和 DROP PARTITION 子句。
-- 創建一個空的分區模式的表 create table part_t (x int) partitioned by (month string); -- 創建一個空分區,下麵將從其他源複製數據文件到這個分區 alter table part_t add partition (month='January'); -- 變更相關數據後,執行 REFRESH 語句使得數據對 Impala 可見 refresh part_t; -- 然後,添加下一月份 alter table part_t add partition (month='February'); -- 現在不再需要一月份數據 alter table part_t drop partition (month='January'); -- 假如表是根據月份、年份分區,執行類似語句: -- alter table part_t drop partition (year=2003,month='January'); -- 這將需要 12 個 ALTER TABLE 語句來刪除 2003 整年的數據
分區鍵的值可以是任意常數表達式,不需要引用標中的列(The value specified for a partition key can be an arbitrary constant expression, without any references to columns).例如:
alter table time_data add partition (month=concat('Decem','ber')); alter table sales_data add partition (zipcode = cast(9021 * 10 as string));
使用註意:
在 ALTER TABLE 語句中,必須包括所有的分區列(Whenever you specify partitions in an ALTER TABLE statement, you must include all the partitioning columns in the specification)。
對於內部表(Impala 管理表)和外部表(數據文件在任意位置)來說,之前的絕大多數操作是一致的。唯一的列外是重命名錶;對外部表來說,相關的數據目錄不會被重命名或移動。
假如為了負載均衡的原因,在 impala-shell 會話中連接到了不同的 Impala 節點,可以啟用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被所有 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
註意:重組表和其關聯的數據文件的另一種方法是使用 CREATE TABLE 語句創建一個與原始表不同的表,然後使用 INSERT 語句複製轉換或重新排序的數據到新表。ALTER TABLE 的優勢是避免了數據文件的重覆複製,允許你使用熟悉的 Hadoop 技術以一種節省空間的方式來重組巨大容量的數據。
語句類型: DDL
ALTER VIEW 語句
修改視圖裡的查詢,或相關的資料庫和/或視圖的名稱。
因為視圖是一種純邏輯結構(一個查詢的別名)沒有實際的數據,ALTER VIEW 只執行 metastore 資料庫中元數據的修改,不涉及 HDFS 中的任意數據文件。
ALTER VIEW [database_name.]view_name AS select_statement ALTER VIEW [database_name.]view_name RENAME TO [database_name.]view_name
假如為了負載均衡的原因,在 impala-shell 會話中連接到了不同的 Impala 節點,可以啟用 SYNC_DDL 查詢選項以使得每一 DDL 語句在新的或修改的元數據被所有 Impala 節點接受前等待,直到都被接受後才返回。參考 SYNC_DDL 瞭解詳細信息。
例子:
create table t1 (x int, y int, s string); create table t2 like t1; create view v1 as select * from t1; alter view v1 as select * from t2; alter view v1 as select x, upper(s) s from t2;
執行 DESCRIBE FORMATTED 語句來查看視圖的定義,這將顯示原始 CREATE VIEW 中的查詢:
[localhost:21000] > create view v1 as select * from t1; [localhost:21000] > describe formatted v1; Query finished, fetching results ... +------------------------------+------------------------------+----------------------+ | name | type | comment | +------------------------------+------------------------------+----------------------+ | # col_name | data_type | comment | | | NULL | NULL | | x | int | None | | y | int | None | | s | string | None | | | NULL | NULL | | # Detailed Table Information | NULL | NULL | | Database: | views | NULL | | Owner: | cloudera | NULL | | CreateTime: | Mon Jul 08 15:56:27 EDT 2013 | NULL | | LastAccessTime: | UNKNOWN | NULL | | Protect Mode: | None | NULL | | Retention: | 0 | NULL | | Table Type: | VIRTUAL_VIEW | NULL | | Table Parameters: | NULL | NULL | | | transient_lastDdlTime | 1373313387 | | | NULL | NULL | | # Storage Information | NULL | NULL | | SerDe Library: | null | NULL | | InputFormat: | null | NULL | | OutputFormat: | null | NULL | | Compressed: | No | NULL | | Num Buckets: | 0 | NULL | | Bucket Columns: | [] | NULL | | Sort Columns: | [] | NULL | | | NULL | NULL | | # View Information | NULL | NULL | | View Original Text: | SELECT * FROM t1 | NULL | | View Expanded Text: | SELECT * FROM t1 | NULL | +------------------------------+------------------------------+----------------------+ Returned 29 row(s) in 0.05s
語句類型: DDL
AVG 函數
返回一組數字的均值的聚合函數。它唯一的參數是一個數值列、或者基於列返回數值的函數或表達式(Its single argument can be numeric column, or the numeric result of a function or expression applied to the column value)。指定列中值為 NULL 的行將被忽略。假如表為空,或者輸入 AVG 的值都是 NULL,則 AVG 返回 NULL。
當查詢包含 GROUP BY 子句,返回每一個分組組合的一個值。
返回類型: DOUBLE
例子:
-- 計算所有非空行的均值 insert overwrite avg_t values (2),(4),(6),(null),(null); -- 上面表中的均值是 4: (2+4+6) / 3. 兩個 NULL 值被忽略 select avg(x) from avg_t; -- 計算特定行的均值(Average only certain values from the column) select avg(x) from t1 where month = 'January' and year = '2013'; -- 在計算均值前進行計算 select avg(x/3) from t1; -- 在計算均值前對列進行函數運算 -- 這裡把所有 NULL 的行替換為 0 -- 這樣值為 NULL 的行也會作為均值計算的因數 select avg(isnull(x,0)) from t1; -- 對 string 列使用某些返回值為數字的函數,然後計算均值 -- 假如某行 s 的值包含 NULL,則 length(s) 函數也返回 NULL,該行被忽略 select avg(length(s)) from t1; -- 也可以與 DISTINCT 和/或 GROUP BY 組合使用 -- 返回多於一個的結果 select month, year, avg(page_visits) from web_stats group by month, year; -- 在執行計算前過濾重覆的值 select avg(distinct x) from t1; -- 執行計算後過濾輸出的值 select avg(x) from t1 group by y having avg(x) between 1 and 20;
BETWEEN 操作符
在 WHERE 子句中,將表達式與下限和上限比較。當表達式大於等於下限,並且小於等於上限,則表達式比較成功。假如上限下限互換,也就是說下限大於上限,那麼就不匹配任何值。
語法: expression BETWEEN lower_bound AND upper_bound
數據類型: 通常使用數字類型。適用於任何類型但不是很實用的 BOOLEAN(Works with any data type, although not very practical for BOOLEAN values)。 (BETWEEN false AND true 會匹配所有的 BOOLEAN 值)。必要時使用 CAST() 函數來確保下限和上限值是相容的數據類型。假如必要的時候調用 string 或 date/time 函數來提取或轉換相關的比較部分,特別是值可以轉換成數字的時候。
使用註意:使用短字元串操作數時要當心(Be careful when using short string operands)。以上限的字元串開始的長字元串將不被包含,因為它被認為是大於上限(A longer string that starts with the upper bound value will not be included, because it is considered greater than the upper bound)。例如,BETWEEN 'A' and 'M' 將不會匹配字元串 'Midway'。假如必要,使用例如 upper(), lower(), substr(), trim(), 等等函數以確保比較如預期執行。
例子:
-- 返回1到6月的值,包括1跟6月. select c1 from t1 where month between 1 and 6; -- 返回以'A' 到 'M' 開頭的名字 -- 只檢測第一個字元以確保所有以 'M' 開頭的名稱符合 -- 進行大小寫敏感的比較以配合不同大小寫約定的名稱(Do a case-insensitive comparison to match names with various capitalization conventions) select last_name from customers where upper(substr(last_name,1,1)) between 'A' and 'M'; -- 返回每個月第一周的數據 select count(distinct visitor_id)) from web_traffic where dayofmonth(when_viewed) between 1 and 7;
BIGINT 數據類型
8位元組的整數類型,用於 CREATE TABLE 和 ALTER TABLE 語句。
範圍: -9223372036854775808 .. 9223372036854775807。沒有無符號子類型。
轉換: Impala 自動轉換為浮點類型(FLOAT or DOUBLE)。 使用 CAST() 函數轉換成 TINYINT, SMALLINT, INT, STRING, or TIMESTAMP。數值 N 轉換成 TIMESTAMP 時,是轉換成從 1970年1月1日開始的 N 秒。
相關信息: INT Data Type, SMALLINT Data Type, TINYINT Data Type, Mathematical Functions
BOOLEAN 數據類型
用於 CREATE TABLE 和 ALTER TABLE 語句的數據類型,表示一個單一的 true/false 的選擇。
範圍: TRUE or FALSE。不要使用引號引起 TRUE 和 FALSE 的字元值。你可以使用大寫、小寫或混合格式的值。表中返回的值都是小寫的 true 或 false。
轉換: Impala 不會自動轉換其他類型為 BOOLEAN。可以使用 CAST() 轉換任意 integer 或 float-point 類型為 BOOLEAN: 0 表示 false,其他非零值轉化為 true。STRING 不能轉換為 BOOLEAN,儘管 BOOLEAN 可以轉換為 STRING,其中 true 對應 '1' 而 false 對應 '0'。
相關信息: Conditional Functions
註釋
Impala 支持大家熟悉的 SQL 註釋風格:
- 從 -- 開始的到行尾都被作為註釋而忽略。這種類型的註釋可以單獨出現在一行上,或者所有或部分語句之後
- 從 /* 開始到下一個 */ 結束的文字都被作為註釋而忽略。這種類型的註釋可以跨越多行。這種類型的註釋可以在語句中或者語句之前、之後出現在一行或多行
例如:
-- 本行是表的註釋 create table ...; /* 本還是查詢的多行註釋 */ select ...; select * from t /* 這是查詢的嵌入式註釋 */ where ...; select * from t -- 這是多行命令中的尾部註釋 where ...;
比較操作
Impala 支持大家熟悉的比較操作用於檢測相等、存在併為列數據類型排序:
- =, !=, <>
- IS NULL, IS NOT NULL
- <, <=, >, >=
- BETWEEN lower_bound AND upper_bound
- LIKE, REGEXP (僅支持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 Statement, Table Statistics, and Column Statistics。
例子:
本例中展示了 T1 和 T2 兩個表,其中 T1.ID 和 T2.PARENT 存在父子關係,有少量的不同的值鏈接。T1 是小表,而 T2 大概有 100K 行。最初,統計信息包括物理度量如文件的數量,總大小,以及定長列如 INT 類型的大小度量。未知值表示為 -1。為每個表運行 COMPUTE STATS 之後,SHOW STATS 語句中有更多信息可用。假如你運行一個涉及這兩個表的連接查詢,你需要統計這兩個表以獲得最優化的查詢。
[localhost:21000] > show table stats t1; Query: show table stats t1 +-------+--------+------+--------+ | #Rows | #Files | Size | Format | +-------+--------+------+--------+ | -1 | 1 | 33B | TEXT | +-------+--------+------+--------+ Returned 1 row(s) in 0.02s [localhost:21000] > show table stats t2; Query: show table stats t2 +-------+--------+----------+--------+ | #Rows | #Files | Size | Format | +-------+--------+----------+--------+ | -1 | 28 | 960.00KB | TEXT | +-------+--------+----------+--------+ Returned 1 row(s) in 0.01s [localhost:21000] > show column stats t1; Query: show column stats t1 +--------+--------+------------------+--------+----------+----------+ | Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size | +--------+--------+------------------+--------+----------+----------+ | id | INT | -1 | -1 | 4 | 4 | | s | STRING | -1 | -1 | -1 | -1 | +--------+--------+------------------+--------+----------+----------+ Returned 2 row(s) in 1.71s [localhost:21000] > show column stats t2; Query: show column stats t2 +--------+--------+------------------+--------+----------+----------+ | Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size | +--------+--------+------------------+--------+----------+----------+ | parent | INT | -1 | -1 | 4 | 4 | | s | STRING | -1 | -1 | -1 | -1 | +--------+--------+------------------+--------+----------+----------+ Returned 2 row(s) in 0.01s [localhost:21000] > compute stats t1; Query: compute stats t1 +-----------------------------------------+ | summary | +-----------------------------------------+ | Updated 1 partition(s) and