postgresql 在posgresql性能中枚举与文本数据类型

9jyewag0  于 5个月前  发布在  PostgreSQL
关注(0)|答案(3)|浏览(62)

我在postgresql中有一个列是文本数据类型。但它实际上总是包含4种值,这些是:

EOS,EOS in 6 months,EOS in 12 months, EOS in 24 months

字符串
我总是执行相同类型的查询,这将取决于用户输入,但它将包含一个或多个上述值,如下所示:

select * from table
where text_column in 
('EOS','EOS in 6 months','EOS in 12 months', 'EOS in 24 months')


我想知道如果我将数据类型从文本转换为枚举,是否会获得任何性能好处?

v9tzhpje

v9tzhpje1#

我想知道如果我将数据类型从文本转换为枚举,是否会获得任何性能好处?
是的,你会-显然如此。Here's an example benchmark在100 k样本:
| 变体|平均执行时间-越低越好|
| --|--|
| 带索引的枚举列|00:00:00.174101|
| 带索引的文本列|00:00:00.193802|
| 无索引枚举列|00:00:00.20623|
| 无索引文本列|00:00:00.299419|
实际上,enum占用4个字节,这比基于text的标签占用(1)更轻,因此更容易处理|4)+长度压缩。我假设你已经有了一个,但如果你没有,你也可以看到添加一个index比改变类型更有帮助,两者可以一起工作。
如果你想更进一步,你可以减少到2个字节,如果你使用一个带有smallint主键的字典表,或者单字符text/char。你可以更进一步,像PostgreSQL内部那样使用1字节的"char"(与charchar(1)不同)。缺点是它需要连接和查找来基于标签的文本表示进行查询,这可能不方便甚至破坏兼容性。
您可能还希望完全丢弃此标签,并在应该获得End-Of-S(服务?)状态时将该字段替换为精确的timestamptz / date,或者如果此标签基于另一个字段指示EOS时刻,则替换为interval,如purchase_datecreated_atsubscription_startpremiere_date

hs1ihplo

hs1ihplo2#

这里唯一简单的答案是“你需要对它进行基准测试”。
话虽如此,如果你文本这个列的平等(记住,in运算符只是一种编写多个平等测试的奇特方式),并且你为该列提供了有限数量的有效值,那么使用枚举是有意义的-值更短(单个整数值与更长的字符串),因此它将存储更多的complex,从而更有效地读取磁盘。
TL;DR -在这里使用枚举可能是一个好主意,但您应该对其进行基准测试。

mwngjboj

mwngjboj3#

ENUM被编码为4个字节,因此您将保存几个字节。
性能应该稍微快一点,但没有什么壮观的。
您可以在创建ENUM时指定排序顺序,这很有用,因为文本按顺序排序,所以'6 months'在'24 months'之后,因为'6'>'2'.
最重要的是,如果你没有在TEXT字段上定义一个约束,那么就不能保证该列只包含一个允许的值。如果应用程序中有一个bug,它可以插入任何东西。ENUM将确保该列只包含一个允许的值。

相关问题