Nic*_*age 2 query-optimization cassandra datastax-java-driver
我目前在Cassandra中设置了一个表,该表具有text,decimal或date类型的列,并带有business_date和account_number 的复合分区键。对于该表的查询,我需要能够支持给定日期的单个帐户或帐户列表的查询。
例:
select x,y,z from my_table where business_date = '2019-04-10' and account_number IN ('AAA', 'BBB', 'CCC')
//Note: Both partition keys are provided for this query
Run Code Online (Sandbox Code Playgroud)
我一直在努力解决与访问此数据有关的性能问题,因为我注意到等待模式很难理解/解释。
在许多情况下,客户端应用程序可以在短时间内总共运行相同的精确查询三次。对于这些情况,我发现三分之二的请求的响应时间(800毫秒)确实很差,其中一个请求的响应时间非常快(50毫秒)。起初我以为这是由于键或行缓存引起的,但是我不确定,因为我相信如果这是真的,那么三个请求中的第三个请求应该总是最快的,事实并非如此。 。
我认为我面临的第二个问题是实际的数据模型本身。尽管查询是在提供所有分区键的情况下提交的,但由于它是一个IN子句,因此结果将是单独的分区,并且可以分布在整个群集中,因此,这将是错误的访问模式。但是,即使运行单个帐户查询,我也会看到这些延迟问题。另外,我看到15到20个帐户附带的查询的性能非常好(在50毫秒以下),因此我不确定数据模型是否确实存在问题。
集群设置:
Java驱动程序集:
在真正确定此问题的根本原因方面,有人对我应关注的事情有任何想法/线索吗?
使用IN的分区键始终是坏主意,即使是复合分区键。分区键的值定义了数据在群集中的位置,分区键的不同值很可能会将数据放置到不同的服务器上。在这种情况下,协调节点(接收到查询)将需要联系保存数据的节点,等待这些节点传递结果,然后再将结果发送回去。
如果需要查询多个分区键,则异步发出单个查询并在客户端收集结果会更快。
另外,请注意,TokenAware策略在您使用时最有效PreparedStatement-在这种情况下,驱动程序能够提取分区键的值,并找到哪个服务器为其保存数据。