Hive - Varchar vs String ,如果存储格式是 Parquet 文件格式,有什么优势吗?



我有一个HIVE表,它将容纳数十亿条记录,它是一个时间序列数据,所以分区是每分钟。每分钟我们将有大约 100 万条记录。

我的表中有几个字段,VIN 号(17 个字符(,状态(2 个字符(...等

所以我的问题是在表创建过程中,如果我选择使用 Varchar(X( 与字符串,是否存在任何存储或性能问题,

瓦尔查尔的几个限制是 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-string

  1. 如果我们提供超过"x"个字符,它将静默截断,因此 保持字符串将是面向未来的。

    1. 非泛型 UDF 不能直接使用 varchar 类型作为输入参数 或返回值。可以改为创建字符串 UDF,并且 varchar 值将被转换为字符串并传递给 UDF。 要直接使用 varchar 参数或返回 varchar 值, 创建一个泛型 UDF。

    2. 可能还有其他上下文不支持 varchar,如果他们 依靠基于反射的方法来检索类型信息。 这包括一些 SerDe 实现。

在存储和性能方面,使用字符串而不是 varchar 需要支付的成本是多少

让我们尝试从 API 中如何实现它来理解它:-

org.apache.hadoop.hive.ql.io.parquet.write.DataWritableWriter 

这是魔术开始的-->

private DataWriter createWriter(ObjectInspector inspector, Type type) {
case stmt.....
........
case STRING:
return new StringDataWriter((StringObjectInspector)inspector);
case VARCHAR:
return new VarcharDataWriter((HiveVarcharObjectInspector)inspector);
}

DataWritableWriter类的createWriter方法检查列的数据类型,即varcharstring,因此它为这些类型创建编写器类。

现在让我们继续VarcharDataWriter类。

private class VarcharDataWriter implements DataWriter {
private HiveVarcharObjectInspector inspector;
public VarcharDataWriter(HiveVarcharObjectInspector inspector) {
this.inspector = inspector;
}
@Override
public void write(Object value) {
String v = inspector.getPrimitiveJavaObject(value).getValue();
recordConsumer.addBinary(Binary.fromString(v));
}
}

StringDataWriter

private class StringDataWriter implements DataWriter {
private StringObjectInspector inspector;
public StringDataWriter(StringObjectInspector inspector) {
this.inspector = inspector;
}
@Override
public void write(Object value) {
String v = inspector.getPrimitiveJavaObject(value);
recordConsumer.addBinary(Binary.fromString(v));
}
}

两个类中的addBinary方法实际上都添加了编码数据类型(编码UTF8编码(的二进制值。而对于字符串编码不同于瓦尔查尔的编码。

问题的简短回答:-字符串和 varchar 的 Unicode 编码是不同的。 存储方面,它可能根据编号而几乎没有变化。 存储的字节数。但根据我的理解,性能方面,蜂巢是schema on read工具。ParquetRecordReader知道如何阅读记录。它只读取字节。因此,不会因 varchar 或字符串数据类型而产生任何性能差异。

最好的方法是使用字符串。varchar 也在内部存储为字符串。如果确实要数据类型,请根据需要在相同数据的基础上创建视图。

我看到的唯一区别是字符串是无界的,最大值为 32,767 字节,而 Varchar 是有界的。字符串有效地限制数据(如果它不使用它(。

矢量化支持也可用于字符串。

我的情况是限制并将讨论重点放在ORC格式上,因为它已成为Hive存储的默认标准。我不认为性能真的是Hive本身的VARCHAR和STRING之间的问题。当涉及到ORC格式时,数据的编码(请参阅下面的链接(在两种情况下都是相同的。即使您使用自定义Serde,这也适用,它都被视为STRING并应用编码。

对我来说,真正的问题是其他第三方工具和编程语言如何使用STRING。如果最终用途没有记录在案的 STRING 问题,则很容易将 STRING 作为类型而不是 VARCHAR(n( 类型。当使用需要通过管道映射元素的 ETL 并且您不想承担忽略大小错误的风险时,这尤其有用。回到第三方工具,例如,SAS 在连接到 Hive 时读取 STRING 类型时存在许多记录的问题。对于某些人来说,它将成为痛苦的领域,而对于某些人来说,这将是他们各自架构中的一个意识点。例如,通过 JDBC 或 ODBC 连接到 Hive 的数据库可能会将数据读取为 VARCHAR(max(,这可能意味着需要考虑许多挑战。

我建议将此视为一个主要因素,而不是Hive本身的性能。到目前为止,我还没有遇到任何表明 VARCHAR 在决定要使用的类型方面比 STRING 表现更好的内容。

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC#LanguageManualORC-StringColumnSerialization

另一点是 VARCHAR 现在支持矢量化。在任何情况下,接收 VARCHAR 的 UDF 将被视为 STRING,因此点为否定。

感谢您纠正我,以防您发现理解不同。此外,可以提供可能会有所帮助的参考链接。

相关内容

  • 没有找到相关文章

最新更新