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()的主要内容,如果未能解决你的问题,请参考以下文章