如果我将 primary key 设置为INT类型(AUTO_INCREMENT)或将其设置为UUID,这两者在数据库性能(SELECT,INSERT等)方面有什么区别?为什么?
INT
AUTO_INCREMENT
UUID
SELECT
INSERT
gorkyyrv1#
UUID返回一个universal unique identifier(如果导入到另一个DB,也希望是唯一的)。引用MySQL文档(强调我的):UUID被设计为一个在空间和时间上全局唯一的数字。对UUID()的两次调用预计会生成两个不同的值,即使这些调用是在两台彼此未连接的单独计算机上执行。另一方面,简单的INT主ID密钥(例如 AUTO_INCREMENT)将为特定DB和DB表返回一个 * 唯一整数 *,但该整数不是通用唯一的**(因此,如果导入到另一个DB,可能会有主键冲突)。在性能方面,使用auto-increment和UUID应该没有任何明显的区别。大多数帖子(包括本网站作者的一些帖子)都是这样说的。当然,UUID可能会花费更多的时间(和空间),但这对于大多数(如果不是全部)情况来说并不是性能瓶颈。将列设置为Primary Key应该使两个选择都等于性能。参见以下参考文献:
auto-increment
Primary Key
GUID
Autoincrement
ID
UUID优点/缺点(改编自Primary Keys: ID s versus GUID s)GUID优点
where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'
newsequentialid()
我会仔细阅读上面提到的参考资料,并根据我的用例决定是否使用UUID。也就是说,在许多情况下,UUID s确实更可取。例如,可以生成UUID s而根本不使用/访问数据库,或者甚至使用已经预先计算和/或存储在其他地方的UUID s。另外,您可以轻松地概括/更新您的数据库模式和/或集群方案,而不必担心ID的破坏和导致冲突。在可能的冲突方面,例如使用v4 UUID(随机),在103万亿个版本4 UUID中找到重复的概率是十亿分之一。
nbnkbykc2#
UUID密钥不能被pk,除非持久化在DB中,因此在此之前将发生往返,在没有成功事务的情况下,您不能假定其pk。大多数UUID使用基于时间,基于mac,基于名称或一些随机的uuid。考虑到我们正在大量转向基于容器的部署,并且它们具有启动序列的模式,依赖于mac地址的MAC地址将不起作用。基于时间并不能保证,因为假设系统总是处于精确的时间同步,这有时并不正确,因为时钟不会遵循规则。GUID不能保证冲突永远不会发生,只是在给定的短时间内它不会发生,但如果有足够的时间和并行运行的系统以及保证最终失败的系统的激增。http://www.ietf.org/rfc/rfc4122.txt
a5g8bdjr3#
对于使用集群主键的MySQL,如果将版本4随机生成的UUID用作主键,将损害插入性能。这是因为它需要对行重新排序,以便将新插入的行放置在聚集索引内的正确位置。顺便说一下,PostgreSQL使用堆而不是集群主键,因此使用UUID作为主键不会影响PostgreSQL的插入性能。有关更多信息,本文对UUID和Int进行了更全面的比较:Choose Primary Key - UUID or Auto Increment Integer
3条答案
按热度按时间gorkyyrv1#
UUID
返回一个universal unique identifier(如果导入到另一个DB,也希望是唯一的)。引用MySQL文档(强调我的):
UUID被设计为一个在空间和时间上全局唯一的数字。对UUID()的两次调用预计会生成两个不同的值,即使这些调用是在两台彼此未连接的单独计算机上执行。
另一方面,简单的
INT
主ID密钥(例如 AUTO_INCREMENT)将为特定DB和DB表返回一个 * 唯一整数 *,但该整数不是通用唯一的**(因此,如果导入到另一个DB,可能会有主键冲突)。在性能方面,使用
auto-increment
和UUID
应该没有任何明显的区别。大多数帖子(包括本网站作者的一些帖子)都是这样说的。当然,UUID
可能会花费更多的时间(和空间),但这对于大多数(如果不是全部)情况来说并不是性能瓶颈。将列设置为Primary Key
应该使两个选择都等于性能。参见以下参考文献:UUID
or not toUUID
?的GUID
vsAutoincrement
UUID
vsauto-increment
in cakephp-mysql的UUID
performance in MySQL?的ID
s versusGUID
s (coding horror)的(
UUID
与auto-increment
的性能结果,改编自Myths,GUID
vsAutoincrement
)x1c 0d1x的数据
UUID
优点/缺点(改编自Primary Keys:ID
s versusGUID
s)GUID
优点ID
,而不必往返于数据库。GUID
列GUID
缺点where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'
)GUID
应该是部分顺序的,以获得最佳性能(例如,SQL 2005上的newsequentialid()
),并允许使用聚集索引。注意事项
我会仔细阅读上面提到的参考资料,并根据我的用例决定是否使用
UUID
。也就是说,在许多情况下,UUID
s确实更可取。例如,可以生成UUID
s而根本不使用/访问数据库,或者甚至使用已经预先计算和/或存储在其他地方的UUID
s。另外,您可以轻松地概括/更新您的数据库模式和/或集群方案,而不必担心ID
的破坏和导致冲突。在可能的冲突方面,例如使用v4 UUID(随机),在103万亿个版本4 UUID中找到重复的概率是十亿分之一。
nbnkbykc2#
UUID密钥不能被pk,除非持久化在DB中,因此在此之前将发生往返,在没有成功事务的情况下,您不能假定其pk。大多数UUID使用基于时间,基于mac,基于名称或一些随机的uuid。考虑到我们正在大量转向基于容器的部署,并且它们具有启动序列的模式,依赖于mac地址的MAC地址将不起作用。基于时间并不能保证,因为假设系统总是处于精确的时间同步,这有时并不正确,因为时钟不会遵循规则。GUID不能保证冲突永远不会发生,只是在给定的短时间内它不会发生,但如果有足够的时间和并行运行的系统以及保证最终失败的系统的激增。
http://www.ietf.org/rfc/rfc4122.txt
a5g8bdjr3#
对于使用集群主键的MySQL,如果将版本4随机生成的UUID用作主键,将损害插入性能。这是因为它需要对行重新排序,以便将新插入的行放置在聚集索引内的正确位置。
顺便说一下,PostgreSQL使用堆而不是集群主键,因此使用UUID作为主键不会影响PostgreSQL的插入性能。
有关更多信息,本文对UUID和Int进行了更全面的比较:Choose Primary Key - UUID or Auto Increment Integer