跳转至

Parquet 空值(Nulls)

在 Apache Parquet 中,空值(NULL)是通过定义级别(Definition Levels)进行编码的,并且这些定义级别采用运行长度编码(Run-Length Encoding, RLE)。NULL 值不会直接存储在数据编码中

例如,在一个非嵌套(non-nested)模式的表结构中,假设某列有 1000 个 NULL 值,那么它的编码方式如下: - 定义级别(Definition Levels)会使用运行长度编码存储 (0, 1000),即表示该列的所有 1000 条记录都是 NULL 值。 - 数据部分不会存储任何额外的信息,因为 NULL 值本身无需编码。


📌 最佳实践

  1. 避免不必要的 NULL 值

    • 尽量减少数据表中 NULL 值的使用,特别是在高基数(high cardinality)的列中,因为即使 Parquet 高效压缩 NULL 值,它们仍然会影响查询优化和存储效率。
    • 在设计表结构时,优先考虑使用默认值(如 0、空字符串)代替 NULL,除非 NULL 语义对业务逻辑至关重要。
  2. 利用 NULL 值的高效存储特性

    • 由于 Parquet 采用运行长度编码(RLE)处理 NULL 值,如果某列中 NULL 值高度集中(如大部分数据为空),会得到极高的压缩比。
    • 但在低密度 NULL 值的情况下(即 NULL 值分散存在),Parquet 仍然会存储定义级别信息,因此可能不会带来显著的存储优化。
  3. 查询优化技巧

    • 在查询 Parquet 数据时,尽量使用 IS NULLIS NOT NULL 来过滤数据,而不是 = 进行比较,因为 NULL 并不会存储在数据块中,而是通过定义级别来标识。
    • 使用 列式存储引擎(如 Apache Spark、Presto、DuckDB),这些引擎针对 Parquet 格式做了优化,可以更高效地处理 NULL 值查询。
  4. 分区(Partitioning)与 NULL 处理

    • 在大规模数据集的设计中,避免对 NULL 进行分区,因为 NULL 可能会导致数据分布不均,进而影响查询性能。
    • 如果 NULL 值数量较多,考虑使用占位值(如 unknownN/A)来替代 NULL,并在查询时进行转换。

通过合理管理 NULL 值,可以更好地提升 Parquet 文件的存储效率和查询性能。🚀