cassandra 如何在同一分区内执行多个范围查询?

gpfsuwkq  于 12个月前  发布在  Cassandra
关注(0)|答案(2)|浏览(104)

我们希望在同一行的不同范围内检索几列。目前我们的查询看起来像(key是分区键)。SELECT column1, value FROM tablename WHERE key = ?key AND column1 >= ?sliceStart AND column1 < ?sliceEnd。查询可以工作,但是它经常返回比应用程序所需的更多的数据,因为应用程序不需要整个切片,而只需要切片操作中的一些较小的部分。
我们尝试改变方法,使用相同的查询,但异步查询多个较小的切片。我们发现,在我们的情况下,通过单个切片查询获取10列比通过单独的较小并行CQL查询(使用DataStax Java Driver 4.16.0)获取10列快3.6倍。
我们还尝试重写查询,通过一个CQL查询获取相同的10列,但使用IN语句。即SELECT column1, value FROM tablename WHERE key = ?key AND column1 IN (?column1, ?column2, ?column3, ?column4, ..., ?column10)。我们发现,在我们的情况下,这个查询只比SELECT column1, value FROM tablename WHERE key = ?key AND column1 >= ?sliceStart AND column1 < ?sliceEnd慢17-20%,但它的执行速度比10个单独的CQL范围查询快得多。
不幸的是,由于应用程序的要求,我们不能使用简单的相等比较,而是需要检索指定范围内的所有列。换句话说,我们希望能够为同一个key选择多个列范围(即同一行)。理想情况下,我们应该使用OR语句,但CQL不支持它。CQL也不支持IN语句中的范围。
也就是说,CQL现在不支持这个查询:SELECT column1, value FROM tablename WHERE key = ?key AND (column1 >= ?sliceStart1 AND column1 < ?sliceEnd1 OR column1 >= ?sliceStart2 AND column1 < ?sliceEnd2 OR ...)
也不支持此查询:SELECT column1, value FROM tablename WHERE key = ?key AND column1 IN (range(?sliceStart1, ?sliceEnd1), range(?sliceStart2, ?sliceEnd2), range(?sliceStart3, ?sliceEnd3), ...)
还有哪些方法可以用来查询同一分区键的多个列范围?

blpfk2vs

blpfk2vs1#

  • 我们发现,在我们的情况下,通过单个切片查询获取10列比通过单独的较小并行CQL查询获取10列快3.6倍(使用DataStax Java Driver 4.16.0)。

在较小的切片上并行异步查询将是一个推荐的解决方案,不幸的是,如果我理解正确的话,你正在针对同一个分区。因此,即使您分割成更小的切片,相同的节点也会得到负载,并且性能不会得到改善。

  • 我们还尝试重写查询,通过单个CQL查询获取相同的10列,但使用IN语句。*

避免使用IN语句。负载从您的机器移动到协调器,协调器将需要像您自己一样分发查询。

  • 不支持OR关键字。*

CQL语言正在不断发展,在CEP-29CEP-30中支持NOT和Vector Search,但我不知道OR

建议方案

如上所述,推荐的方法是较小切片的异步查询。如果性能影响对您来说太重要,我可以想到两种方法:

  • 将第一个可以工作但在应用程序端进行过滤的查询保留在内存中。这并不像听起来那么糟糕。
  • 调优(是什么原因导致较小的片上的争用?节点上的CPU、执行池...我会调查并在可能的情况下增加)。
hm2xizp9

hm2xizp92#

快速的回答是否定的,在设计上,不可能在一个SELECT语句中执行多个范围查询。
不可能做到这一点的原因是相当有意的。
当我想到你的目标时,我想到两件事:要么(1)你的数据模型错了,要么(2)你有一个分析用例。
此查询执行速度快的原因是因为数据在磁盘上按顺序排序,因此不需要额外的磁盘寻道:

SELECT ... FROM table WHERE key = ? AND column1 >= ? AND column1 < ?

我的建议是在客户端进行额外的过滤以限制结果。干杯!

相关问题