我正在使用PostgreSQL(9.4)数据库在Ruby on Rails中开发应用程序。在我的用例中,表中的列将被非常频繁地查找,因为应用程序的重点是在模型上搜索非常特定的属性。
我目前正在决定是使用一种integer
类型还是只使用典型的字符串类型(例如character varying(255)
,Rails中的默认字符串类型)作为列,因为我不确定索引的性能会有什么不同。
这些列是枚举。对于具有的可能值的数量,它们具有固定的大小。大多数枚举长度不超过5,这意味着该索引在应用程序的整个生命周期中或多或少是固定的;因此,整数和字符串索引的节点数将相同。
但是,将被索引的字符串可能长约20个字符,这在内存中大约是整数的5倍(如果整数是4个字节,并且字符串是每个字符1个字节的纯ASCII,则成立)。我不知道数据库引擎怎么做索引查找窗口,但如果它需要“扫描”的字符,直到它匹配准确,那么在本质上这意味着该字符串查找就超过5倍的整数查找速度较慢; 直到匹配整数查找为止的“扫描”将是4个字节而不是20个字节。这就是我的想象:
查找值为(整数)4:
正在扫描.........................找到| 正在获取记录... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
查找值是(字符串)“ some_val”(8个字节):
扫描................................................. ....................................发现| 正在获取记录... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
我希望这是有道理的。基本上,因为整数占用的空间较小,所以它的“匹配”速度比字符串对应的速度更快。也许这是一个完全错误的猜测,但是我不是专家,所以这就是为什么我问你们!我想我刚刚找到的答案似乎支持我的假设,但我想确定。
列中可能使用的任何一个值都不会改变,因此索引本身也不会改变(除非我向枚举添加了新值)。在这种情况下,使用integer
或会不会产生性能差异varchar(255)
,或者使用整数类型是否更有意义?
我问的原因是Rails的enum
类型将整数映射到字符串键,但它们并不意味着是面向用户的列。本质上,您无法验证枚举值是有效值,因为无效值会ArgumentError
在运行任何验证之前引起一个。使用string
类型可以进行验证,但是如果有性能损失,我宁愿绕开验证问题。
varchar(255)
vs. ,SQL Server中没有隐藏的优化varchar(260)
。SQL Server 6.x可能存在这种情况,但很长一段时间以来并非如此。