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



我想知道,与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(*)的版本比使用resultSet.all().size() == 0要快得多。我使用CQLSH来尝试以下查询哪个更快,这应该等于java的查询:

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

和慢的那个

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

为两个选项调用System.currentTimeMillis()并将其打印出来。如果毫秒级精度不够,试试System.nanoTime()

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

您必须从网络流量的角度考虑这两个查询,这不仅适用于cassandra,也适用于通过网络的任何请求(例如jdbc请求,rest请求)

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

当你执行这个查询,然后你调用ResultSet#all你正在检索所有(*)分区(其中where子句显然持有)到进程的内存,使用数据驱动程序和实例化一个ArrayList与所有行的,最后调用一个简单的列表#大小。你必须记住延迟是邪恶的

(*)请注意,当查询检索的行数大于获取大小时,all方法也可能在网络上产生多个请求。这是更多的延迟!

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

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

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

最新更新