Vertica NEXTVAL()函数-如何通过条件在记录级别调用它?



我使用的是Vertica Analytic Database v9.2.1-20,

使用NEXTVAL()

在记录级别上通过条件获取下一个序列值。函数。下面是示例

CREATE SEQUENCE v_seq START 1;
CREATE TABLE test_seq (id INT, flag int);
INSERT INTO test_seq VALUES (1, 0);
INSERT INTO test_seq VALUES (2, 1);
INSERT INTO test_seq VALUES (3, 1);
INSERT INTO test_seq VALUES (4, 0);
INSERT INTO test_seq VALUES (5, 0);
INSERT INTO test_seq VALUES (6, 1);
INSERT INTO test_seq VALUES (7, 1);
SELECT  id,
flag,
CASE 
WHEN flag = 0 THEN NEXTVAL('v_seq') 
ELSE CURRVAL('v_seq') 
END as group_id
FROM test_seq 
ORDER BY ID;

预期结果:

id  flag    group_id
1   0       1
2   1       1
3   1       1
4   0       2
5   0       3
6   1       3
7   1       3

实际结果:

id  flag    group_id
1   0       1
2   1       2
3   1       3
4   0       4
5   0       5
6   1       6
7   1       7

看起来就像不管WHEN条件是什么,都在调用NEXTVAL()函数。

是否有办法通过条件调用它?

谢谢!

我的几个测试-在Vertica 10中-导致了您上面报告的相同行为。

似乎没有办法让它做你想做的事。

如前所述,您可以使用CONDITIONAL_TRUE_EVENT(flag=0) OVER(ORDER BY id)来获得所需的结果。

存在速度慢的风险,因为您的OLAP窗口规范中没有PARTITION BY,因此在大表的情况下运行单线程。

但是一个大的表将被分割。

在使用seq.nextval的分段表中,表的每个部分/段将以不同的倍数启动您使用的序列,默认情况下为250,000。在节点1中,序列从1开始,在节点2中,序列从250,000开始,在节点3中从500,000开始,以此类推。如果表没有分段,序列生成器也会导致单线程进程,从而降低性能。所以你现在正处于进退两难的境地....

如果表是分段的,您可以并行化CONDITIONAL_TRUE_EVENT()调用,方法是在OLAP函数调用中使用基本表的分段标准作为PARTITION by标准。

我遇到了一个类似的问题。vertica处理多个节点序列的方式是导致核心问题的原因(即使只有一个节点)。由于系统必须执行目录锁定(跨集群中的所有节点),因此序列被分配为大块。您可以更改块大小,但这不是特别有用。

为了解决这个问题,主要是获取一个可控数量的顺序值,我们缓存它们并从Java内存中分配它们。一旦数据库分配了它们,它们就不会被重新分配。这将使你更接近你想要达到的目标,但需要更多的工作。

最新更新