当数据已经被分区和交换时的窗口交换操作

kx7yvsdv  于 2021-05-16  发布在  Spark
关注(0)|答案(1)|浏览(454)

下面的查询是交换数据,以便对两个数据集中已经交换了数据的列执行row\u number()
桌上有30个木桶,桌上有一个带扣的table

explain
select

* 

from
(
select  *,
row_number() over(partition by Incident_Number order by Incident_Number) as rnk
from
    (
        select  *
    from
        (
        select /*+ REPARTITION(30,Incident_Number) */ * 
        from austin_crime_data_new
        union all
        select *
        from crime_parquet_table
        ) tmp
    )t
) d
where rnk = 1

下面是解释计划。我认为+交换(7)是没有必要的。如果你们不这么想,告诉我原因。

== Physical Plan ==

* Filter (10)

+- Window (9)
   +- * Sort (8)
      +- Exchange (7)
         +- Union (6)
            :- Exchange (3)
            :  +- * Project (2)
            :     +- Scan csv  (1)
            +- * ColumnarToRow (5)
               +- Scan parquet default.crime_parquet_table (4)
5gfr0r5j

5gfr0r5j1#

我用下面的替代方法解决了这个问题,因为union all并不把它看作是一个特例。它只是把这个和其他table一样对待
所以首先,我把中间数据也保存为一个带方框的表

create table crime_parquet_table2
using parquet
CLUSTERED BY (Incident_Number) INTO 30 BUCKETS
location 'path2'
select /*+ REPARTITION(30,Incident_Number) */ * 
from austin_crime_data_new

现在我创建了一个表,使用like和两个路径(每个路径都有带方框的数据)

CREATE TABLE crime_data like crime_parquet_table2
location 'path1,path2'
;

现在这个新表上的sql给出了预期的计划

explain
select *
from
(
select * ,
row_number() over(partition by Incident_Number order by Incident_Number) as rnk
from crime_data
) 
where rnk = 1

计划

== Physical Plan ==

* Filter (5)

+- Window (4)
   +- * Sort (3)
      +- * ColumnarToRow (2)
         +- Scan parquet default.crime_data (1)

因此,额外的工作是将中间数据持久化到一个存储器中,但洗牌被消除了

相关问题