1 limit語句優化
eg.select *from table_name <where pa2='' <and pa3='xx'>> limit 100
在 Hive 中, 由於表的數據量往往較大, 以上語句都會被優化 (set hive.fetch.task.conversion = none 會被關閉這項優化, 強制起 MR 作業; 默認配置值為 more); 這些語句的運行,都會通過過濾文件的處理方式查詢結果並返回, 而不是起 MR 任務提交到 Yarn 上執行返回, 這一點在運行日志中可以看出; 在表或分區數據量較小, 而且查詢過濾條件命中的條目較多是會較快返回; 但是當由於表或分區數據量巨大, 或者命中條數很少而達不到 limit 的條數時, 過濾文件的操作就會一直進行到滿足 limit 或者過濾 完文件所有數據才返回, 反而變得更慢。
表或者分區數據量多情況下,如果滿足的數據量多,那么過濾某文件很快能返回值;如果數據量很少,是不加limit限制,那么MR查詢所有,也可以很快返回。
如果查詢的 where 子句中的字段過濾條件命中率不高, 建議不要帶 limit 子句 (但強烈建議分區表查詢時帶上分區!!!)
如果非要帶limit,加上:set hive.fetch.task.conversion = none;
Fetch Task功能:
一個簡單的查詢語句,是指一個沒有函數、排序等功能的語句,當開啟一個Fetch Task功能,就執行一個簡單的查詢語句不會生成MapRreduce作業,而是直接使用FetchTask,從hdfs文件系統中進行查詢輸出數據,從而提高效率。
2 case when語句報錯
when 后面的表達式應該類型保持一致
3 修正ctas的表數據錯行問題
直接select可能沒問題,創建新表時:
CREATE
TABLE
table_name_new as select ,,, from table_name
WHERE
dt=
''
;
這時候查詢table_name_new可能會出現錯位,解決辦法:
CREATE
TABLE
table_name_new store
as
parquet
as select ,,, from table_name
WHERE
dt=
''
;
原因:table_name_new數據格式是 Textfile 格式, 默認的行分隔符為 \n,列分隔符為 \001; 所以當數據中有換行符時解析時會被換行,為了正確解析帶有特殊字符的數據, 建議將表存儲為 PARQUET 或者其他 Hive 支持的數據格式; 這樣帶特殊字符的字段將不會再錯行或者錯列。
4 查詢表時文件格式出錯
報錯信息:
org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable cannot be cast to org.apache.hadoop.io.BinaryComparable 或 org.apache.hadoop.hive.ql.io.orc.OrcStruct cannot be cast to org.apache.hadoop.io.BinaryComparable
這是因為表存儲為 RCFILE 或 ORCFILE, 而表的 SERDE 設置的序列化反序列化類不適配, 使用以下語句修改, 如果是分區表, 分區也需要使用 alter 或 msck 重建 (Hive 的元數據表 SDS 中存儲了表和分區的序列化反序列化等屬性)
-- 只 serde 不同時示例 alter table ${database}.${table} set serde 'org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe'; -- field.delim 等也不同時示例 alter table ${database}.${table} set serde 'org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe' WITH SERDEPROPERTIES ('field.delim' = '\001', 'serialization.format' = '\001');
5 表查詢子目錄遞歸問題
當 (非分區) 數據表目錄下有子目錄時, 使用 MR 引擎可能查不出數據或查不到部分數據, 因為默認 MR 是不會讀取表目錄下的子目錄數據的, 例子:
hive> dfs -ls hdfs://XX/detail_tmp1; Found 5 items drwxr-xr-x - hive hadoop 0 2018-08-07 14:46 hdfs://XX/detail_tmp1/1 drwxr-xr-x - hive hadoop 0 2018-08-02 15:05 hdfs://XX/detail_tmp1/2 drwxr-xr-x - hive hadoop 0 2018-08-02 15:06 hdfs://XX/detail_tmp13 drwxr-xr-x - hive hadoop 0 2018-08-02 15:05 hdfs://XX/detail_tmp1/4 drwxr-xr-x - hive hadoop 0 2018-08-02 15:06 hdfs://XX/detail_tmp1/5
表目錄下無文件但有子目錄, MR 引擎默認不會遞歸到子目錄所以查不出數據;
使用 set hive.execution.engine = tez 將引擎切換到 TEZ, 查詢即可有數, 這是因為在 切換為TEZ 引擎下時, Hive 會將 mapred.input.dir.recursive 和 mapreduce.input.fileinputformat.input.dir.recursive 設置為 true, 查詢時會遞歸目錄;
如果在同一個會話下, 再將引擎切回至 MR, 則會發現也能查出數據了, 因為之前在 TEZ 引擎下執行了語句, 已將 mapred.input.dir.recursive 和 mapreduce.input.fileinputformat.input.dir.recursive 設置為 true 了。
部分引擎會默認將 mapred.input.dir.recursive 和 mapreduce.input.fileinputformat.input.dir.recursive 這兩個屬性設置為 true