NULL 排序顺序

默认情况下,投影列值按升序存储,但是 NULL 值的位置取决于列的数据类型。

ORDER BY 子句的 NULL 位置差异

分析 OVER(window-order-clause) 与 SQL ORDER BY 子句的语义稍有不同:

OVER(ORDER BY ...)

分析窗口排序子句使用 ASCDESC 排序顺序来确定分析函数结果的 NULLS FIRSTNULLS LAST 位置。NULL 值按如下方式放置:

  • ASC, NULLS LAST — NULL 值出现在排序结果的末尾。

  • DESC, NULLS FIRST — NULL 值出现在排序结果的开头。

(SQL) ORDER BY

SQL 和 Vertica ORDER BY 子句产生不同的结果。SQL ORDER BY 子句只指定升序或降序排序顺序。Vertica ORDER BY 子句根据列数据类型确定 NULL 位置:

  • NUMERIC、INTEGER、DATE、TIME、TIMESTAMP 和 INTERVAL 列: NULLS FIRST (NULL 值出现在排序投影的开头。)

  • FLOAT、STRING 和 BOOLEAN 列: NULLS LAST (NULL 值出现在排序投影的末尾。)

NULL 排序选项

在执行分析计算的查询中,如果不在意 NULL 的位置,或者您知道列中不包含任何 NULL 值,请指定 NULLS AUTO,而不考虑数据类型。Vertica 选择性能最快的放置,如以下查询所示。否则,请指定 NULLS FIRSTNULLS LAST

=> SELECT x, RANK() OVER (ORDER BY x NULLS AUTO) FROM t;

如以下示例所示,您可以仔细构建查询,使 Vertica 避免对数据排序并提高查询速度。如 OVER(ORDER BY) 子句指定的那样,Vertica 会在列 x 上对来自表 t 的输入进行排序,然后对 RANK() 求值:

=> CREATE TABLE t (
    x FLOAT,
    y FLOAT );
=> CREATE PROJECTION t_p (x, y) AS SELECT * FROM t
   ORDER BY x, y UNSEGMENTED ALL NODES;
=> SELECT x, RANK() OVER (ORDER BY x) FROM t;

在之前的 SELECT 语句中,Vertica 不再使用 ORDER BY 子句,而且能迅速执行查询,因为列 x 是 FLOAT 数据类型。因此,投影排序顺序与分析默认排序 (ASC + NULLS LAST) 相匹配。当底层投影已经经过排序后,Vertica 也可以避免对数据进行排序。

但是,如果列 x 是 INTEGER 数据类型,则 Vertica 必须对数据进行排序,因为 INTEGER 数据类型的投影排序顺序 (ASC + NULLS FIRST) 与默认分析排序 (ASC + NULLS LAST) 不匹配。要帮助 Vertica 消除排序,请指定 NULL 的位置以与默认排序匹配:

=> SELECT x, RANK() OVER (ORDER BY x NULLS FIRST) FROM t;

如果列 x 是 STRING,以下查询就会消除排序:

=> SELECT x, RANK() OVER (ORDER BY x NULLS LAST) FROM t;

如果在之前的查询中忽略了 NULLS LAST,Vertica 会消除排序,因为 ASC + NULLS LAST 对于分析 ORDER BY 子句和 Vertica 中字符串相关的列来说是默认排序规范。

另请参阅