Greenplum实现nulls first/last改写

在pg中支持nulls first/last的写法,并且因为pg的索引中可以存储null值,所以这种写法还支持索引。
而在Greenplum之前的版本中是不支持这种写法的:

select * from tbl order by id nulls first;  
  
select id, last_value(key) over (partition by gid order by crt_time nulls first) from tbl ;   

但是在新版本的Greenplum中可以使用了,并且也支持索引扫描,但是如果不支持这种写法我们该怎么改写呢?

其实要实现nulls first/last这种语法我们只要在排序时调整字段nulls排在前面还是后面即可。所以我们可以改写成:

select * from tbl order by (id is not null), id;  

相当于

select * from tbl order by id nulls first;  

select * from tbl order by (id is null), id;  
  

相当于

select * from tbl order by id nulls last;  

例如:

postgres=# select * from t4 order by (id is not null),id;
 id |               info               
----+----------------------------------
    | e8a03a9114ad7e2a20a089bc8e976ced
    | eda4245be143d05d873bd7a96543e741
    | 7ec3032fd84ae3377173aff3e0affff2
    | 6fb3808909322badc94e542dbc011d0f
  1 | acb6661d320f25133476670879b154ab
  2 | acb6661d320f25133476670879b154ab
  3 | acb6661d320f25133476670879b154ab
  4 | acb6661d320f25133476670879b154ab
  5 | acb6661d320f25133476670879b154ab
(9 rows)

postgres=# select * from t4 order by (id is null),id;    
 id |               info               
----+----------------------------------
  1 | acb6661d320f25133476670879b154ab
  2 | acb6661d320f25133476670879b154ab
  3 | acb6661d320f25133476670879b154ab
  4 | acb6661d320f25133476670879b154ab
  5 | acb6661d320f25133476670879b154ab
    | e8a03a9114ad7e2a20a089bc8e976ced
    | eda4245be143d05d873bd7a96543e741
    | 7ec3032fd84ae3377173aff3e0affff2
    | 6fb3808909322badc94e542dbc011d0f
(9 rows)

同样在窗口函数中我们也可以这样实现,不过两者还是有一些区别,我们这种写法是不能使用索引的。

postgres=# EXPLAIN  select * from t4 order by (id is null),id;
                                       QUERY PLAN                                       
----------------------------------------------------------------------------------------
 Gather Motion 2:1  (slice1; segments: 2)  (cost=9513.72..9763.75 rows=100009 width=37)
   Merge Key: (id IS NULL), id
   ->  Sort  (cost=9513.72..9763.75 rows=50005 width=37)
         Sort Key: (id IS NULL), id
         ->  Seq Scan on t4  (cost=0.00..1208.09 rows=50005 width=37)
 Settings:  enable_seqscan=on
 Optimizer status: legacy query optimizer
(7 rows)

而普通的nulls first/last语法则可以使用索引。

postgres=# EXPLAIN select * from t4 order by id nulls last;
                                     QUERY PLAN                                      
-------------------------------------------------------------------------------------
 Gather Motion 2:1  (slice1; segments: 2)  (cost=0.00..9415.27 rows=100009 width=37)
   Merge Key: id
   ->  Index Scan using idx_t4 on t4  (cost=0.00..9415.27 rows=50005 width=37)
 Settings:  enable_seqscan=on
 Optimizer status: legacy query optimizer
(5 rows)

你可能感兴趣的:(Greenplum)