在vertica中将数据类型从身份更改为身份(1,1,1)
ALTER datatype from identity to identity(1,1,1) in vertica
我们已经创建了 vertica tables,其 ID 列的数据类型为 Identity。
问题是每次会话关闭或 table 截断 ID 值都会跳到 250000、500000 等等(vertica 中的缓存默认为 250000)。我知道如果我们将缓存更改为 1,这将不是问题。
所以我的问题是我们如何更改列以将数据类型从 identity 更改为 identity(1,1,1) ?还是创建一个新的 table 并加载数据是我唯一的选择?
有什么方法可以重新设置身份列?
在我告诉您如何执行此操作后,请阅读注意事项。这真的很重要。我会提前为演讲道歉。
您不能修改更新版本的 Vertica 中的 IDENTITY
或 AUTO_INCREMENT
列...至少不能直接修改。但是,您可以通过更改引擎盖下生成的序列来解决您的问题。
找到你的序列:
SELECT * FROM SEQUENCES
WHERE identity_table_name = 'mytable';
然后您应该找到与您的标识字段相对应的自动生成的序列(但是,如果您重命名了您的列,名称可能不匹配)。
从那里您可以更改它并更改缓存值。
ALTER SEQUENCE mytable_id_seq CACHE 1000;
您也可以重新启动这些值(例如在截断之后)。
ALTER SEQUENCE mytable_id_seq RESTART WITH 1;
您必须重新启动任何使用这些序列的会话才能使更改生效。一旦缓存被拉出,该缓存仍然是会话的一部分。
也就是说,我觉得在 Vertica 中提及一些关于序列的事情真的很重要。序列缓存真的很重要。来自序列的每个未缓存的拉取都是一个全局目录锁。如果过于频繁,这将阻止某些非常重要的操作在您的集群上发生。
例如,假设您将缓存设置为 1,然后多次执行 insert/select。您只是反复锁定了全局目录。孤立地,您甚至可能不会注意到这一点,但是在一个有大量工作的繁忙集群上,您肯定会注意到这一点。
另一个例子是糟糕的会话处理。假设我做了一些疯狂的事情,比如登录、插入一行并注销(不要介意单行插入通常对 Vertica 不利的事实)。不管你有多少缓存,你仍然会重复支付那个目录锁。
因此,如果您在 Vertica 中使用序列,请务必了解您打算如何使用序列。另一种替代方法可能是使用 UUID(在 Vertica 中不可用),使用 HASH()
,使用自然键访问您的数据,或者在数据到达 Vertica 之前生成它们。
除非您真的只是偶尔插入一行,否则不要这样做。
另一件需要提及的重要事情是,您真的不应该使用序列作为一种排序形式。这更像是一种最佳实践,对于任何数据库都是如此。首先,如果你并行加载,它不会真正具有代表性,因为使用了缓存块(并且没有缓存,你可以忘记任何类型的性能,因为我提到的原因除了并行序列拉动大大加剧)。其次,这就是时间戳的用途。你甚至可以默认这个。
由此得出的一个推论是,在使用序列时总是会出现间隙。造成序列缺口的情况太多了。几乎任何数据库也是如此。我可能是错的,但我不相信任何数据库回滚序列会导致事务回滚。
我们已经创建了 vertica tables,其 ID 列的数据类型为 Identity。
问题是每次会话关闭或 table 截断 ID 值都会跳到 250000、500000 等等(vertica 中的缓存默认为 250000)。我知道如果我们将缓存更改为 1,这将不是问题。
所以我的问题是我们如何更改列以将数据类型从 identity 更改为 identity(1,1,1) ?还是创建一个新的 table 并加载数据是我唯一的选择?
有什么方法可以重新设置身份列?
在我告诉您如何执行此操作后,请阅读注意事项。这真的很重要。我会提前为演讲道歉。
您不能修改更新版本的 Vertica 中的 IDENTITY
或 AUTO_INCREMENT
列...至少不能直接修改。但是,您可以通过更改引擎盖下生成的序列来解决您的问题。
找到你的序列:
SELECT * FROM SEQUENCES
WHERE identity_table_name = 'mytable';
然后您应该找到与您的标识字段相对应的自动生成的序列(但是,如果您重命名了您的列,名称可能不匹配)。
从那里您可以更改它并更改缓存值。
ALTER SEQUENCE mytable_id_seq CACHE 1000;
您也可以重新启动这些值(例如在截断之后)。
ALTER SEQUENCE mytable_id_seq RESTART WITH 1;
您必须重新启动任何使用这些序列的会话才能使更改生效。一旦缓存被拉出,该缓存仍然是会话的一部分。
也就是说,我觉得在 Vertica 中提及一些关于序列的事情真的很重要。序列缓存真的很重要。来自序列的每个未缓存的拉取都是一个全局目录锁。如果过于频繁,这将阻止某些非常重要的操作在您的集群上发生。
例如,假设您将缓存设置为 1,然后多次执行 insert/select。您只是反复锁定了全局目录。孤立地,您甚至可能不会注意到这一点,但是在一个有大量工作的繁忙集群上,您肯定会注意到这一点。
另一个例子是糟糕的会话处理。假设我做了一些疯狂的事情,比如登录、插入一行并注销(不要介意单行插入通常对 Vertica 不利的事实)。不管你有多少缓存,你仍然会重复支付那个目录锁。
因此,如果您在 Vertica 中使用序列,请务必了解您打算如何使用序列。另一种替代方法可能是使用 UUID(在 Vertica 中不可用),使用 HASH()
,使用自然键访问您的数据,或者在数据到达 Vertica 之前生成它们。
除非您真的只是偶尔插入一行,否则不要这样做。
另一件需要提及的重要事情是,您真的不应该使用序列作为一种排序形式。这更像是一种最佳实践,对于任何数据库都是如此。首先,如果你并行加载,它不会真正具有代表性,因为使用了缓存块(并且没有缓存,你可以忘记任何类型的性能,因为我提到的原因除了并行序列拉动大大加剧)。其次,这就是时间戳的用途。你甚至可以默认这个。
由此得出的一个推论是,在使用序列时总是会出现间隙。造成序列缺口的情况太多了。几乎任何数据库也是如此。我可能是错的,但我不相信任何数据库回滚序列会导致事务回滚。