【问题标题】:PagingState for Statement in CQLCQL 中语句的 PagingState
【发布时间】:2015-10-26 21:34:56
【问题描述】:

我试图了解 PagingState 如何与 Cassandra 中的 Statement 一起使用。我尝试使用将几 1000 条记录插入数据库的示例,并尝试从数据库中读取相同的数据,并将获取大小设置为 10 并使用分页状态。这工作得很好。这是我的示例junit代码:

@Before
public void setup() {
    cassandraTemplate.executeQuery("create table if not exists pagesample(a int, b int, c int, primary key(a,b))");
    String insertQuery = "insert into pagesample(a,b,c) values(?,?,?)";
    PreparedStatement insertStmt = cassandraTemplate.getConnection().prepareStatement(insertQuery);
    for(int i=0; i < 5; i++){
        for(int j=100; j<1000; j++){
            cassandraTemplate.executeQuery(insertStmt, new Object[]{i, j, RandomUtils.nextInt()});
        }
    }
}

@Test
public void testPagination() {
    String selectQuery = "select * from pagesample where a=?";
    String pagingStateStr = null;
    for(int run=0; run<90; run++){
        ResultSet resultSet = selectRows(selectQuery, 10, pagingStateStr, 1);
        int fetchedCount = resultSet.getAvailableWithoutFetching();
        System.out.println(run+". Fetched size: "+fetchedCount);
        for(Row row : resultSet){
            System.out.print(row.getInt("b")+", ");
            if(--fetchedCount == 0){
                break;
            }
        }
        System.out.println();

        PagingState pagingState = resultSet.getExecutionInfo().getPagingState();
        pagingStateStr =  pagingState.toString();
    }
}

public ResultSet selectRows(String cql, int fetchSize, String pagingState, Object... bindings){
    SimpleStatement simpleStatement = new SimpleStatement(cql, bindings);
    statement.setFetchSize(fetchSize);
    if(StringUtils.isNotEmpty(pagingState)){
        statement.setPagingState(PagingState.fromString(pagingState));
    }
    return getSession().execute(simpleStatement);
}

当我执行这个程序时,我看到 testPagination 中的每次迭代都准确地打印了 10 条记录。但这是文档所说的:

  • 请注意,设置获取大小并不意味着 Cassandra 将 总是返回确切的行数,有可能它 返回或多或少的结果。

我不太明白为什么 Cassandra 返回的行数与 fetch size 中指定的行数不完全相同。当查询中没有提供 where 子句时,是否会出现这种情况?当查询受限于分区键时,它会返回确切数量的记录吗?请澄清。

【问题讨论】:

    标签: java cassandra datastax cql nosql


    【解决方案1】:

    来自CQL protocol specification

    客户也不应该断言没有结果会超过result_page_size 结果。虽然当前实现始终尊重 result_page_size 的确切值,我们保留在未来出于性能原因返回稍微更小或更大的页面的权利

    因此,最好始终依赖 getAvailableWithoutFetching 而不是页面大小,以防 Cassandra 将来更改其实现。

    【讨论】:

    • 抱歉,隔了这么久才来澄清。根据答案,事情将来可能会发生变化,但我想了解这个答案是否适用于这两种情况,即 a) where 子句限制在分区键上的查询和 2) 对于没有任何 where 子句的查询?
    • 是的,它适用于任何查询,无论 where 子句如何。
    • 感谢您的澄清。但我无法准确地得到它。如果数据分布在多个节点上,那么 Cassandra 可能会提供稍微更少/更多的行数。但是当我的查询基于分区键子句时,由于所有数据都进入特定节点,为什么 Cassandra 不能给出确切的结果数量?你能帮我理解吗?
    猜你喜欢
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 2023-03-13
    • 2016-12-14
    • 2020-02-08
    • 2016-05-06
    相关资源
    最近更新 更多