KingbaseESV8R3对于order by null列的处理

背景

客户遇到一个现象order by 列是null的时候,最后一行总是显示相同的值。不要问我为什么对空值排序,意义何在?客户代码如此,客户不愿意改代码,作为dba大家都懂的。客户认为即使对null排序也能实现普通列的效果。要么定位为bug,要不给出合理解释。

分析

下面我们看一下测试过程,可以得出一个公式。select * from aaa order by name limit n offset f;

当表的总记录数 total>2*(n+f) 就得到:最后一行总是显示相同的值

[复制代码](javascript:void(0)😉

TEST=# \d+ aaa;
                          Table "PUBLIC.AAA"
 Column |  Type   | Modifiers | Storage  | Stats target | Description
--------+---------+-----------+----------+--------------+-------------
 EE     | INTEGER |           | plain    |              |
 NAME   | TEXT    |           | extended |              |

TEST=# select * from aaa;
 EE | NAME
----+------
  1 |
  2 |
  3 |
  4 |
  5 |
  6 |
  7 |
  8 |
  9 |
 10 |
 11 |
(11 rows)

TEST=# select * from aaa order by name limit 2 offset 0;
 EE | NAME
----+------
  2 |
  1 |
(2 rows)

TEST=# select * from aaa order by name limit 2 offset 1;
 EE | NAME
----+------
  3 |
  1 |
(2 rows)

TEST=# select * from aaa order by name limit 2 offset 2;
 EE | NAME
----+------
  4 |
  1 |
(2 rows)

TEST=# select * from aaa order by name limit 2 offset 3;
 EE | NAME
----+------
  5 |
  1 |
(2 rows)

注意:根据公式 当 limit 2 offset 4 结果集排序如预期
TEST=# select * from aaa order by name limit 2 offset 4;
 EE | NAME
----+------
  5 |
  6 |
(2 rows)
这正满足公式,total=11>(2+4) 不满足 ,所以排序结果正常。

[复制代码](javascript:void(0)😉

结论

好了,这下我们了解的其对于null排序的内部算法,常规排序是所有记录都保存下来再进行排序,对于limit语句排序节点进行了优化,

如:select * from aaa order by name limit n offset f;

满足两个条件之一,排序节点会进行优化。

1,排序内存不够用

2,表的总记录数total>2*(n+f)

大概的优化是这样,内存中最多只保留(n+f)条记录,新的记录只需要与(n+f)的最大值或者最小值之一进行比较就可以快速筛掉不满足的纪录。

Note:以上的算法只是猜测,对于相同值的排序是不确定的,两个相同的值,排序的先后是不确定的,不能把结果依赖于不确定性的规律。

posted @ 2022-08-06 11:34  KINGBASE研究院  阅读(97)  评论(0编辑  收藏  举报