Cassandra java查询性能计数(*)或全部()。size()

时间:2015-09-15 12:01:48

标签: java cassandra cassandra-2.0

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

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("coun")==0){
//...
}

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

3 个答案:

答案 0 :(得分:0)

只需为这两个选项调用System.currentTimeMillis()并将其打印出来即可。 如果毫秒精度不够,请尝试System.nanoTime()

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

答案 1 :(得分:0)

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

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

慢一点:

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

答案 2 :(得分:0)

您必须根据网络流量来考虑这两个查询,这不仅适用于cassandra,也适用于网络上的任何请求(例如jdbc请求,休息请求)

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

当你执行这个查询然后你调用ResultSet#时,所有你正在检索所有(*)分区(明显包含where子句)到使用数据存储驱动程序的进程的内存并用所有实例化一个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模型中,不可能保持计数器的一致性),但我认为我的意思很清楚。