CQL中的语句的PagingState

时间:2015-08-04 12:57:04

标签: java cassandra datastax cql nosql

我试图理解PagingState如何在Cassandra中使用Statement。我尝试了一个示例,它将几千条记录插入到数据库中,并尝试从数据库读取相同内容,其中fetch size设置为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子句,是这种情况吗?当查询受限于分区键时,它是否会返回确切的记录数?请澄清。

1 个答案:

答案 0 :(得分:4)

来自CQL protocol specification

  

客户也不应断言任何结果都不会超过result_page_size个结果。虽然目前的实施始终尊重result_page_size的确切价值,但我们保留将来出于性能原因返回稍微更小或更大页面的权利

因此,如果Cassandra将来更改其实施,那么始终依赖getAvailableWithoutFetching代替页面大小是一种很好的做法。