【发布时间】:2016-07-07 08:15:13
【问题描述】:
我们创建了具有 ID 列的垂直表,其数据类型为 Identity。
问题是每次关闭会话或截断表时,ID 值都会跳转到 250000、500000 等等(vertica 中的缓存默认为 250000)。我知道如果我们将缓存更改为 1,这将不是问题。
所以我的问题是我们如何更改列以将数据类型从身份更改为身份(1,1,1)?还是创建一个新表并加载数据是我唯一的选择?
有没有办法重新设置身份列?
【问题讨论】:
我们创建了具有 ID 列的垂直表,其数据类型为 Identity。
问题是每次关闭会话或截断表时,ID 值都会跳转到 250000、500000 等等(vertica 中的缓存默认为 250000)。我知道如果我们将缓存更改为 1,这将不是问题。
所以我的问题是我们如何更改列以将数据类型从身份更改为身份(1,1,1)?还是创建一个新表并加载数据是我唯一的选择?
有没有办法重新设置身份列?
【问题讨论】:
在我告诉您如何执行此操作后,请阅读注意事项。这真的很重要。我会提前为这次讲座道歉。
您不能在最新版本的 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,然后多次执行插入/选择。您只是反复锁定了全局目录。孤立地看,您甚至可能不会注意到这一点,但是在一个繁忙的集群中,您肯定会注意到这一点。
另一个例子是糟糕的会话处理。假设我做了一些疯狂的事情,比如登录、插入一行并注销(不要介意单行插入通常对 Vertica 不利)。不管你有多少缓存,你仍然会重复支付目录锁。
因此,如果您在 Vertica 中使用序列,请务必注意您计划如何使用它们。另一种替代方法可能是使用 UUID(在 Vertica 中不可用)、使用 HASH()、使用自然键来访问您的数据,或者在数据到达 Vertica 之前生成它们。
除非您真的只是每隔一段时间才真正插入一行,否则不要这样做。
另一件重要的事情是你真的不应该使用序列作为排序的一种形式。这更像是一种最佳实践,对于任何数据库都是如此。首先,如果您进行并行加载,它不会真正具有代表性,因为使用了缓存块(并且没有缓存,由于我提到的原因,您可以忘记任何类型的性能,除非通过并行序列拉取大大加剧)。其次,这就是时间戳的用途。你甚至可以默认这个。
由此得出的结论是,在使用序列时总是期望有间隙。导致序列空缺的情况太多了。这几乎适用于任何数据库。我可能是错的,但我不相信任何数据库回滚序列都会拉动事务回滚。
【讨论】: