Hive 配置单元中的排序表(ORC文件格式)

Hive 配置单元中的排序表(ORC文件格式),hive,orc,Hive,Orc,我在确保利用配置单元表中的排序数据时遇到了一些困难。(使用ORC文件格式) 我知道我们可以通过在CREATEDDL中声明一个distributeby子句来影响从配置单元表读取数据的方式 CREATE TABLE trades ( trade_id INT, name STRING, contract_type STRING, ts INT ) PARTITIONED BY (dt STRING) CLUSTERED BY (trade_id) SORTED BY

我在确保利用配置单元表中的排序数据时遇到了一些困难。(使用ORC文件格式)

我知道我们可以通过在CREATEDDL中声明一个
distributeby
子句来影响从配置单元表读取数据的方式

CREATE TABLE trades
(
    trade_id INT,
    name STRING,
    contract_type STRING,
    ts INT
)
PARTITIONED BY (dt STRING)
CLUSTERED BY (trade_id) SORTED BY (trade_id, time) INTO 8 BUCKETS
STORED AS ORC;
这意味着每次我对该表进行查询时,数据都将按
trade\u id
在各个映射器之间分发,然后将其排序

我的问题是:

我不希望将数据拆分为
N
文件(bucket),因为容量没有那么大,我会使用小文件

但是,我确实希望利用排序插入

INSERT OVERWRITE TABLE trades
PARTITION (dt)
SELECT trade_id, name, contract_type, ts, dt
FROM raw_trades
DISTRIBUTE BY trade_id
SORT BY trade_id;
我真的需要在CREATEDLL语句中使用
CLUSTERED/SORT
?或者Hive/ORC是否知道如何利用插入过程已确保数据已排序这一事实

这样做有意义吗

CLUSTERED BY (trade_id) SORTED BY (trade_id, time) INTO 1 BUCKETS

带扣桌子是一个过时的概念

您不需要在DDL表中写入CLUSTERED BY

加载表时,使用
按分区键分发
以减少减压器上的压力,尤其是在写入ORC时,这需要中间缓冲区来构建ORC,如果每个减压器加载多个分区,则可能导致OOM异常

当表较大时,可以使用bytes.per.reducer限制最大文件大小,如下所示:

set hive.exec.reducers.bytes.per.reducer=67108864;--or even less
如果您有更多的数据,将启动更多的还原程序,创建更多的文件。这比装载固定数量的铲斗更灵活

这也会更好,因为对于小表,您不需要创建更小的存储桶

ORC具有内部索引和bloom过滤器

如果由于数据倾斜和数据量大,按分区键分发是不够的,那么还可以随机分发。如果数据分布均匀,最好按列分布。如果不是,则随机分配,以避免单个长时间运行的减速器问题

最后,您的insert语句可能如下所示:

set hive.exec.reducers.bytes.per.reducer=33554432; --32Mb per reducer

INSERT OVERWRITE TABLE trades PARTITION (dt)
SELECT trade_id, name, contract_type, ts, dt
FROM raw_trades
DISTRIBUTE BY dt,                    --partition key is a must for big data
              trade_id,              --some other key if the data is too big and key is
                                     --evenly distributed (no skew)   
              FLOOR(RAND()*100.0)%20 --random to distribute additionally on 20 equal parts 

SORT BY contract_type; --sort data if you want filtering by this key 
                       --to work better using internal index
不要在表DDL中使用CLUSTERED BY,因为在插入过程中使用DISTRIBUTE BY、ORC w索引和bloom filters+SORT可以更灵活地实现相同的功能

Distribute+sort可以将ORC文件的大小减少3倍或4倍。类似的数据可以更好地压缩,并使内部索引更有效

还请阅读以下内容:
这是关于排序的相关答案:

您在问题的开头提到了DISTRIBUTE BY,但显然是指CLUSTERED BY。要回答您的问题,请注意,这是使用预排序的数据信息优化配置单元查询的唯一方法。在不生成聚集表的情况下对数据进行排序还可以提高原始ORC在压缩或查找已排序列方面的性能(因为ORC保留每个文件的最小/最大统计数据)。但是,如果您希望配置单元优化器利用排序后的信息,则需要一个带扣的表。如果表很小,只有一个bucket可能有意义,但是如果表很小,为什么还要优化它?@leftjoin——如果我们必须在某个键上连接两个表,那么使用distribute by加载这两个表的工作方式将与bucketing工作方式相同?我们还需要在两个表中使用RAND函数平均分配文件吗?如果文件是ORC,那么它将是内部索引和数据有效打包。启用ppd后,它将完美工作。当您编写文件时,分发同样有助于避免由于倾斜而导致减速器运行缓慢。当读取ORC时,文件被拆分,如果大小不同,则不会出现问题。