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:以上的算法只是猜测,对于相同值的排序是不确定的,两个相同的值,排序的先后是不确定的,不能把结果依赖于不确定性的规律。
KINGBASE研究院