问题现象
OceanBase 数据库 V4.x 版本中 Oracle 租户下,一条包含 sample() 和 rownum 的 SQL,执行查询返回结果不随机。
关键信息
预期返回数据是随机的,而下方 SQL 执行结果一致,不符合预期。
obclient [SYS]> select NAME from TEST2024 sample(3) where ROWNUM < 10;
+------------+
| NAME |
+------------+
| iy`"50ib)3 |
| y |
| cwad |
| (m}j |
| *4zawj}om |
| kxzaa#<t5$ |
| h4v |
| 29 |
| *k8h |
+------------+
9 rows in set (0.002 sec)
obclient [SYS]> select NAME from TEST2024 sample(3) where ROWNUM < 10;
+------------+
| NAME |
+------------+
| iy`"50ib)3 |
| y |
| cwad |
| (m}j |
| *4zawj}om |
| kxzaa#<t5$ |
| h4v |
| 29 |
| *k8h |
+------------+
9 rows in set (0.002 sec)
obclient [SYS]> select NAME from TEST2024 sample(3) where ROWNUM < 10;
+------------+
| NAME |
+------------+
| iy`"50ib)3 |
| y |
| cwad |
| (m}j |
| *4zawj}om |
| kxzaa#<t5$ |
| h4v |
| 29 |
| *k8h |
+------------+
9 rows in set (0.002 sec)
执行计划如下。
obclient [SYS]> explain select NAME from TEST2024 sample(3) where ROWNUM < 10;
+---------------------------------------------------------------------------------------------------------------------------------+
| Query Plan |
+---------------------------------------------------------------------------------------------------------------------------------+
| ========================================================= |
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| --------------------------------------------------------- |
| |0 |EXCHANGE IN REMOTE | |9 |9 | |
| |1 |└─EXCHANGE OUT REMOTE| |9 |8 | |
| |2 | └─TABLE FULL SCAN |TEST2024|9 |4 | |
| ========================================================= |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([TEST2024.NAME]), filter(nil) |
| 1 - output([TEST2024.NAME]), filter(nil) |
| 2 - output([TEST2024.NAME]), filter(nil), rowset=16 |
| access([TEST2024.NAME]), partitions(p0) |
| limit(cast(CEIL(10) - cast(1, NUMBER(-1, -1)), BIGINT(-1, 0))), offset(nil), is_index_back=false, is_global_index=false, |
| range_key([TEST2024.__pk_increment]), range(MIN ; MAX)always true |
+---------------------------------------------------------------------------------------------------------------------------------+
15 rows in set (0.004 sec)
问题原因
SQL 改写过程中没有维护 sample 信息,改写后丢失 sample 信息,生成了错误的算子 TABLE FULL SCAN,没有走随机采样逻辑,导致 SQL 查询结果返回不随机,预期正确的算子应该是 TABLE ROW SAMPLE SCAN。
问题的风险及影响
SQL 查询返回结果集不随机。
影响租户
影响 OceanBase 数据库中的 Oracle 租户,对于 SYS 租户和 MySQL 租户无影响。
适用版本
OceanBase 数据库 V4.x 版本。
解决方法
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库 V4.2.1 BP2(oceanbase-4.2.1.2-102010012023120119)。
规避方式
SQL 添加 Hint /*+NO_REWRITE*/,或者改写 SQL 为:select * from ( select NAME from TEST2024 sample(3))where ROWNUM < 10;。