有三个键和一个计数器:
A:300个值[A1-> A300]
B:10个值[B1-> B10]
C:400个值[C1-> C400]计数器
有两种设计:
设计1,主键是((A,C),B),(A,C)是分区键,B是簇密钥
查询:select count(*) from XXX where A = A1 and C in ( C91, C92, ..., C200) and B = B1
设计2,主键是(A,B,C),A是分区键,B和C是簇键
查询:select count(*) from XXX where A = A1 and B = B1 and C <= C200 and C> C90
我有两个问题:
Q1,对于类似于select count(*) from XXX where A = A1 and B = B1 and C <= C200 and C> C90
的查询(A1,B1,C200和C90是随机的),在上面两个主键设计中哪个更好?
Q2,IN ()
中可以支持多少个值?
欢迎任何评论。感谢。
答案 0 :(得分:1)
Q1。 设计1更好
因为在你的情况下:
设计1单个分区的最大值可以只是c值的数量
但是对于
设计2单个分区的最大值可以是b * c值的数量
因此,Design 1的搜索空间非常小。它具有很强的可扩展性
Q2。 IN Query支持的最大值为65535
如果您尝试发送数字,如果值大于此值,它将抛出
IllegalArgumentException(&#34; IN子句的值太多,允许的最大值为65535&#34;);
答案 1 :(得分:0)
我认为设计2更好。
假设在设计1中您将发出这类查询:
select count(*) from XXX where A = A1 and C in ( C91, C92, ..., C200) and B = B1
你会给你的协调员带来很大的压力。除非您为少数值执行此操作,否则不建议在分区键级别使用IN
子句。这是因为协调器将在将行返回到客户端之前等待每个分区的结果。如果一个节点出现故障,一切都会失败,您需要重试整个节点。可以找到对此行为的一个很好的解释here。
相反,假设在设计2中你将运行这些类型的查询:
select count(*) from XXX where A = A1 and B = B1 and C <= C200 and C> C90
您将只扫描一个分区,这很好,因为C *将执行范围扫描。一个非常安全的场景,除非您的分区变得非常广泛。