hive中常見問題


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM