phoenix 5.0 CURSOR 游标(二) 不得不说的坑

这个坑很深沉,官方文档太简短了。

这个坑是由:select语句引起的。

也就是声明游标时的查询语句,如下:

 

 

拉开序幕:

这是一张很简单的表test,id是row key,一共15条数据。

 

接着,我们使用游标遍历这个表数据。

public static void main(String[] args) throws SQLException {
        long start = System.currentTimeMillis();
        // 获得连接资源
        Connection con = PhoenixUtils.getConnection();
        ResultSet rset = null;
        // 游标语句
        PreparedStatement statement = con.prepareStatement("DECLARE empCursor CURSOR FOR select * from test");
        statement.execute();
        // 开启游标
        statement = con.prepareStatement("OPEN empCursor");
        statement.execute();

        int countTotal=0;

        // 一次拿2条
        statement = con.prepareStatement("FETCH NEXT 2 ROWS FROM empCursor");
        rset = statement.executeQuery();
        while (rset.next()){
            countTotal++;
            System.out.println(rset.getString("id"));
        }

        System.out.println("countTotal="+countTotal);
        // 关闭游标
        statement = con.prepareStatement("CLOSE empCursor");
        statement.execute();
        // 释放资源
        PhoenixUtils.colseResource(con,statement,rset);
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) +" ms");
    }

执行结果:

拿2条数据,没错只拿到了两条数据!这个逻辑很正常。

 

重点来了,我改了一下声明游标的sql。

DECLARE empCursor CURSOR FOR select * from test

改为:

DECLARE empCursor CURSOR FOR select id from test

只是把查询内容由*号,改为了id,我们继续执行一次,来看看结果。

执行结果:

What???

说好了只拿2条,怎么拿到了16条?

什么什么test表一共就15条数据,怎么会有16条??这是假的吧。冷静、冷静。

 

查下test表的索引有哪些

!indexes test

果然有个二级索引表,接着查下二级索引表内容。

果然有16条数据,执行以下计划看看。

select id from test; 直接走的二级索引表。

这下大概明白问题所在了,原来test是不可变表。出现索引表与原始表,数据不一致,也就正常了。

为了证实我的想法,再修改sql测试下改为:

select age from test; -- age字段不会走二级索引表

执行结果:

 

结论:

申明游标的语句

1、数据如果来自索引表那么会一次性都给到结果集。即使你指定了取的行数。

2、SQL不走索引表,数据来自原表。则会按照你指定的行数,返回结果集。如果你需要遍历全部数据,去统计结果。那么需要在外部增加循环。类似递归。

https://mp.csdn.net/postedit/84875099 不走二级索引表可以参考这个循环。

注意:声明游标的SQL走,二级索引 和 不走二级索引的差别!!!!

(如果是不可变表,那么遍历数据一定不能取索引表,否则统计结果是不正确的。)

 

当然,走表自身的row key是没有问题的。我们还可以使用hint /*+NO_INDEX*/ 来处理,数据遍历二级索引表的情况。

注意:一定要用explain查看sql

 

END,闭幕--

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值