PySpark中BigInt与布尔类型的存储大小对比疑问
嘿,这个问题挺有意思的!我来帮你拆解一下为什么你实验里的两个Delta表大小完全一致~
首先得明确:你预期布尔类型占空间更小是合理的,但实际存储时,底层文件格式的压缩机制、列式存储特性,以及数据的分布情况会抹平这种理论上的差异,具体原因如下:
Parquet(Delta默认存储格式)的压缩魔法
Delta Lake默认用Parquet作为底层存储格式,而Parquet是列式存储+自动压缩的。你生成的0/1(BigInt)和True/False(布尔)都是二值数据,而且分布接近50%随机。这种情况下,Snappy(默认压缩算法)对两种类型的压缩效率几乎一致——不管是重复的0/1还是True/False,压缩算法都会把批量的重复数据压缩到极致,最终数据部分的大小差异微乎其微。Parquet对布尔类型的存储细节
理论上布尔类型只需要1位就能存储,但实际在Spark的Parquet实现中,为了读写效率,布尔值通常是按字节(1字节)存储的;而你的BigInt虽然是8字节的类型,但实际存储的是0和1这种极小的数值,Parquet的编码(比如RLE游程编码)会把连续的相同值打包,8字节的BigInt和1字节的布尔,经过编码压缩后,最终占用的空间几乎没差别。文件元数据的“占比”影响
你的表总大小是5.1MiB,其中除了实际数据,还包含Parquet/Delta的文件元数据(比如列信息、统计信息等)。当数据本身被压缩到很小的时候,元数据的占比会相对固定,这也会让两个表的总大小看起来完全一致。
如果想验证布尔类型的空间优势,可以试试极端场景:比如把所有indicator都设为0(或1),这时候布尔类型的表应该会比BigInt的更小——因为游程编码处理全相同的布尔值时,能做到更极致的压缩。但在你这种随机分布的场景下,两者的压缩效果就拉平啦。
备注:内容来源于stack exchange,提问作者Steven

