加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 索引:如果节点数相同,则为整数与字符串性能

发布时间:2020-12-13 16:20:19 所属栏目:百科 来源:网络整理
导读:我正在使用PostgreSQL(9.4)数据库在 Ruby on Rails中开发一个应用程序.对于我的用例,表中的列将非常频繁地查找,因为应用程序的整个点是在模型上搜索非常特定的属性. 我目前正在决定是使用整数类型还是仅使用典型的字符串类型(例如字符变化(255),which is the
我正在使用PostgreSQL(9.4)数据库在 Ruby on Rails中开发一个应用程序.对于我的用例,表中的列将非常频繁地查找,因为应用程序的整个点是在模型上搜索非常特定的属性.

我目前正在决定是使用整数类型还是仅使用典型的字符串类型(例如字符变化(255),which is the default in Rails),因为我不确定索引的性能差异.

这些列是枚举.它们具有固定的大小,可以获得它们可能具有的值.大多数枚举长度不超过5,这意味着索引在应用程序的整个生命周期中或多或少都是固定的;因此,整数和字符串索引的节点数相同.

但是,要编入索引的字符串可能长约20个字符,在内存中大约是整数的5倍(如果整数是4个字节,并且字符串是每个字符1个字节的纯ASCII,那么这就成立了).我不知道数据库引擎如何对索引进行索引,但是如果它需要“扫描”字符串直到它完全匹配,那么本质上这意味着字符串查找比整数查找慢5倍;直到匹配整数查找的“扫描”将是4个字节而不是20个.这就是我想象的:

查找值为(整数)4:

scanning………………………. FOUND | getting records…
|BYTE_1|BYTE_2|BYTE_3|BYTE_4|BYTE_5|BYTE_6|BYTE_7|BYTE_8|…|

查找值为(string)“some_val”(8字节):

scanning………………………………………………………………………….
FOUND | getting records…
|BYTE_1|BYTE_2|BYTE_3|BYTE_4|BYTE_5|BYTE_6|BYTE_7|BYTE_8|…|

我希望这是有道理的.基本上,因为整数占用较少的空间,所以它可以比其字符串对应物更快地“匹配”.也许这是一个完全错误的猜测,但我不是专家,所以这就是我问你们的原因!我想this answer I just found似乎支持我的假设,但我想确定.

列中可能的值的数量在使用任何一个时都不会改变,因此索引本身不会改变(除非我向枚举添加了新值).在这种情况下,使用整数或varchar(255)会有性能差异,还是使用整数类型更有意义?

我问的原因是Rails的枚举类型将整数映射到字符串键,但它们并不意味着是面向用户的列.实质上,您无法验证枚举值是否有效,因为无效值将导致ArgumentError,然后才能运行任何验证.使用字符串类型将允许验证,但如果有性能成本,我宁愿只是解决验证问题.

简短回答:整数比varchar或文本在每个方面都要快.对于小桌子和/或短键来说无关紧要.差异随着密钥的长度和行数的增加而增加.

string … 20 characters long,which in memory is roughly 5x that of
the integer (if an integer is 4 bytes,and the strings are pure ASCII
at 1 byte per character,then this holds)

确切地说,字符类型(text或varchar)占用磁盘上20个ASCII字符和RAM中23个字节的正好21个字节.详细评估:

> What is the overhead for varchar(n)?

同样重要的是:COLLATION规则可以使排序字符数据更加昂贵 – 与数字数据类型不同:

> Would index lookup be noticeably faster with char vs varchar when all values are 36 chars

在大多数情况下,索引大小可能是性能差异的主要原因.考虑每个索引元组的开销(基本上与表相同):项指针为4个字节,元组头为24个字节.因此,整数的索引元组将达到36个字节(包括4个字节的对齐填充),对于具有20个ASCII字符的varchar(20),它将是52个字节(也包括填充).细节:

> Configuring PostgreSQL for read performance

抛开所有理论:最好只测试:

> Measure the size of a PostgreSQL table row

Postgres 9.5引入了一种用于对长字符串数据进行排序的优化(关键字“缩写键”).但Linux上某些C库函数中的错误迫使该项目禁用Postgres 9.5.2中非C归类的功能. Details in the release notes.

但是,如果您实际使用Postgres枚举类型,则大多数这些注意事项都无关紧要,因为无论如何都会在内部使用整数值实现. The manual:

An enum value occupies four bytes on disk.

旁白:varchar(255)曾经对SQL Server的早期版本有意义,它可以在内部使用更高效的数据类型,最多可达255个字符.但奇数长度限制255个字符对Postgres的性能没有特别的影响.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读