Cassandra java 查询性能 count(*) 或 all().size()

Posted

技术标签:

【中文标题】Cassandra java 查询性能 count(*) 或 all().size()【英文标题】:Cassandra java query performance count(*) or all().size() 【发布时间】:2015-09-15 12:01:48 【问题描述】:

我想知道,结合 java 使用 apache cassandra 哪个更快。我有以下选择来获得我的结果:

Statement s = QueryBuilder.select().from("table").where(QueryBuilder.eq("source",source);
ResultSet resultSet = session.execute(s);
if (resultSet.all().size() == 0) 
  //Do Something

实现我的计数的第二个选项是:

ResultSet rs = session.execute("SELECT COUNT(*) as coun FROM table WHERE source = '"+source+"'");
Row r = rs.one();
if (r.getLong("count") == 0) 
  //Do Something

在每个查询中,最大计数为 1。现在我的问题是,一般来说这会更快。

【问题讨论】:

了解的唯一方法是对其进行分析。但由于第二个不返回该行,我会默认支持该行。 也不行,如果您正在执行 count(*) 之类的分析查询,您可能需要在 cassandra 之上使用 Spark 之类的东西。 【参考方案1】:

我在多个表上测试了几个查询,带有 count(*) 的版本比使用 resultSet.all().size() == 0 快得多。我使用 CQLSH 尝试了以下查询哪个更快,哪个应该等于 java 的:

SELECT COUNT(*) as coun FROM table WHERE source = '...';

还有较慢的:

SELECT * FROM table WHERE source = '...';

【讨论】:

【参考方案2】:

只需致电System.currentTimeMillis() 获取这两个选项并将其打印出来。 如果毫秒精度不够,请尝试System.nanoTime()

long start = System.currentTimeMillis();
<YourMethod>
long end = System.currentTimeMillis();
long dif = end-start;

【讨论】:

确保多次运行查询以获得良好的样本。 NODETOOL 可以在尝试优化 CQLSH 中的查询时提供帮助。【参考方案3】:

你必须从网络流量的角度来考虑这两个查询,这不仅适用于 cassandra,而且适用于网络上的任何请求(例如 jdbc 请求、rest 请求)

SELECT * FROM table WHERE source = '...';

当您执行此查询然后调用 ResultSet#all 时,您正在检索所有 (*) 分区(其中 where 子句显然包含)到使用 datastax 驱动程序并实例化 ArrayList 的进程的内存中行,最后调用一个简单的 List#size。 你要记住Latency is evil

(*) 请注意,当查询检索到的行数大于fetch size 时,all 方法还可以通过网络生成多个请求。这是更多的延迟!

SELECT COUNT(*) as coun FROM table WHERE source = '...';

使用此查询,您也需要支付延迟,但只是不可避免的。也就是说,RTT 将查询发送到 cassandra 集群并接收响应。 由于这将是一个简单的整数,因此不会因为分页而产生多个请求,并且会消耗很少的带宽。

此外,恕我直言,使用选择计数(如果您根本不需要行信息)将是一个更好的选择,因为您明确需要什么,这可以为服务器提供机会(数据库、Web 服务器等)以特定方式处理请求并提高性能。 例如,如果您的查询没有 where 子句并且您只需要总行数,则使用 select count(*) from ... 服务器可以利用每个表的内部计数器并更快地提供查询。但是,this is not the case in cassandra(因为在 cassandra 模型中,不可能保持计数器的一致性),但我认为我的意思很清楚。

【讨论】:

以上是关于Cassandra java 查询性能 count(*) 或 all().size()的主要内容,如果未能解决你的问题,请参考以下文章

带有 COUNT 查询的 Cassandra 超时

Cassandra性能优化--如何提升交叉分区查询性能

cassandra 查询超时

在Cassandra中创建表和创建列家族有什么区别?

cassandra高级操作之分页的java实现(有项目具体需求)

Cassandra 无法从表中查询行总和