我在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')
型
我想知道如果我将数据类型从文本转换为枚举,是否会获得任何性能好处?
3条答案
按热度按时间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"
(与char
或char(1)
不同)。缺点是它需要连接和查找来基于标签的文本表示进行查询,这可能不方便甚至破坏兼容性。您可能还希望完全丢弃此标签,并在应该获得End-Of-S(服务?)状态时将该字段替换为精确的
timestamptz
/date
,或者如果此标签基于另一个字段指示EOS时刻,则替换为interval
,如purchase_date
,created_at
,subscription_start
,premiere_date
。hs1ihplo2#
这里唯一简单的答案是“你需要对它进行基准测试”。
话虽如此,如果你只文本这个列的平等(记住,
in
运算符只是一种编写多个平等测试的奇特方式),并且你为该列提供了有限数量的有效值,那么使用枚举是有意义的-值更短(单个整数值与更长的字符串),因此它将存储更多的complex,从而更有效地读取磁盘。TL;DR -在这里使用枚举可能是一个好主意,但您应该对其进行基准测试。
mwngjboj3#
ENUM被编码为4个字节,因此您将保存几个字节。
性能应该稍微快一点,但没有什么壮观的。
您可以在创建ENUM时指定排序顺序,这很有用,因为文本按顺序排序,所以'6 months'在'24 months'之后,因为'6'>'2'.
最重要的是,如果你没有在TEXT字段上定义一个约束,那么就不能保证该列只包含一个允许的值。如果应用程序中有一个bug,它可以插入任何东西。ENUM将确保该列只包含一个允许的值。