南大通用GBase 8a 通过first_rows的hint提高带limit的简单查询性能

GBase 8a 数据库集群,在执行最简单的 select where limit 时,不包含order, group等复杂操作。GBase 通过first_rows的hint,在系统资源浪费和性能之间取得一定的平衡。

这种最简单的查询,比如查询某个IP的上网记录前100行,有2种执行方案:

select * from t_autoinc where id<200 limit 100;

1、是将命令下发到每个数据节点,并返回limit要求的行数,然后集群再从所有结果种选择需要的行数返回。

2、是挨个节点查询,如果不满足则查询下一个节点。

其中方案1,在节点很多时,比如10个,会造成实际返回的结果行数为10个*100行=1万行,对整体资源来说就是个浪费。
方案2避免了这个问题,但会遇到某些极端情况,比如前面所有的节点行数都不满足100行,最终就是数据库【串行】查询了10个节点,最终整体性能就是每个节点性能的10倍。

而first_row这个hint,可以在中间由用户指定平衡的策略。比如

select /*+first_rows(10)*/ * from t_autoinc where id<200 limit 100;

first_row(10) 则会让所有节点都参与查询,但无需到100行,而是10行就返回调用方,然后继续查询下一批。而负责收集的管理节点,发现各个节点发来的总行数已经达到要求是,会主动关闭各个节点的连接,避免后续浪费资源。

语法

SEELCT /*+ first_rows(n) */ colums FROM table_name LIMIT n;
其中,n 表示每次最小的返回结果集的请求。

使用约束

如果使用gccli或者gncli命令行客户端登录集群时,需要使用-c和-q参数。

-c参数的作用,让hint,也就是/*+ … */不会直接被客户端忽略,会发送到server端。
-q参数,保证在集群的节点上使hint可以起作用。

1、只能对于单表查询时,并且使用了limit关键字,并且limit不能包含offset

2、查询语句中不能包含GROUP BY、ORDERBY、OLAP函数,不支持UNION,但支持UNION ALL。