用于 INNER JOIN 的小表的最佳配置

问题描述

我有许多小表(导出为 CSV 时小于 5k 字节),它们只是“从到”(例如 code to name),并且必须在 JOIN 中使用,只是为了转换内部代码或 ID。 .. 如何在 Hive 上与他们一起使用 CREATE TABLE

示例:

  CREATE TABLE mydb.fromto1(id1 bigint,name1 string);

  CREATE TABLE mydb.fromto2(
     id2 bigint,name2 varchar(10)
  )
  PARTITIONED BY (ingestion_day date)
  ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
  STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
  OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
  LOCATION 'hdfs://TLVBRPRDK/apps/hive/warehouse/mydb.db/fromto2'
  TBLPROPERTIES (
     'orc.compress'='SNAPPY','orc.row.index.stride'='50000','orc.stripe.size'='67108864','transient_lastDdlTime'='1577456923'
  );

  -- INSERT INTO mydb.fromto1 10 lines
  -- INSERT INTO mydb.fromto2 10 lines

  CREATE VIEW mydb.vw_test1 AS -- need for BEST PERFORMANCE HERE!
    SELECT big.*,tiny.name1 
    FROM mydb.big_fact_table big INNER JOIN mydb.fromto1 tiny ON big.id1=tiny.id1
     -- and/or INNER JOIN mydb.fromto2 tiny2 ON big.id2=tiny2.id2
  ;

如何设置正确的参数(分区与否、压缩与否、托管或外部、行格式等)sql JOIN 与大数据中获得最佳性能(事实)表?

是否有“好的快速指南”或向导?


注意:

解决方法

  1. 对于这样的小表,您绝对不需要分区。如果每个表都在单个文件中,而不是分区,而不是分桶,那就更好了。
  2. 使用这些设置进行连接优化(必要时增加数字)。检查EXPLAIN计划,应该是mapjoin操作符,小表可以在同一个mapper上join。
    set hive.auto.convert.join=true;
    set hive.mapjoin.smalltable.filesize=157286400; --if the file size is smaller than this threshold,map join will be used
    
    set hive.auto.convert.join.noconditionaltask = true;
    set hive.auto.convert.join.noconditionaltask.size = 157286400; --combined small tables size
  1. 对小表使用 TEXTFILE 可能比 ORC 更好,因为对于此类小表,纯 TEXTFILE 的大小可能更小。压缩的相同规则 - 只有在有助于显着减小文件大小时才使用压缩,小文件并不总是可以有效压缩(压缩的小文件甚至可以比未压缩的大)。使用 ORC 获得更大的尺寸。检查文件大小并决定。
    请记住,最快的 SerDe 是 LasySimpleSerDe,因此默认的制表符分隔的 TEXTFILE 适用于小文件。对于更大的文件,请使用 ORC 和压缩。

  2. 外部或托管 - 在这种情况下无关紧要。