在进行hive大表操作的时候,我们常常使用分区去进行指定查询以加快查询速度,其实分桶也是一种很好的选择:
1、分桶将文件进行切块,哈希散列,均匀的存储于hdfs中,避免数据倾斜;
2、分桶join的时候,效率更高;
但是也会遇到一些查询方面的问题,如果是分区表,直接指定分区字段即可快速过滤定位到所需查询的数据,但是在分桶表中,无法直接定位到具体的桶。笔者进行相关的搜索和查询MapReduce源码,分桶的操作实际上是对数据进行不同的存储文件中,MapReduce中,多少个分桶即产生不同的reduce个数,即找到他是如何进行reduce分区逻辑即可:
public int getPartition(K key, V value, int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
可以看到,分区原则是key的哈希值 和 int的最大值进行做与运算,保证哈希的值是一个正数,再去余我们的分区数或者分桶数,得到他最终落到哪一个桶。
所以我们可以直接指定桶进行查询:
select id
from table_name tablesample (bucket X out of Y on id)
查询id的具体分桶:
SELECT (hash(id) & 2147483647) % 桶个数 +1
如果我们分桶4个,上面代码具体桶在 1 ,则查询该idSQL可以写
select id
from table_name tablesample (bucket 1 out of 4 on id)
where id = $id