Impala查询 - 优化查询以获取给定键的唯一身份

时间:2017-10-30 06:09:56

标签: sql impala

我正在寻找方法来计算具有特定pkey的唯一用户以及没有该pkey的唯一身份用户的数量。

以下是一个示例表:

 userid |   pkey     | pvalue
------------------------------
   U1   |   x        | vx
   U1   |   y        | vy
   U1   |   z        | vz
   U2   |   y        | vy
   U3   |   z        | vz
   U4   |   null     | null

我得到了预期的结果,以获得拥有pkey =' y'那些没有使用这个查询但结果很昂贵的人:

WITH all_rows AS
  ( SELECT userid, 
           IF( pkey='y', pval, 'none' ) AS val,
           SUM( IF(pkey='y',1,0) ) AS has_key
   FROM some_table 
   GROUP BY userid, val)
SELECT val,
       count(distinct(userid)) uniqs
FROM all_rows
WHERE has_key=1
GROUP BY val
UNION ALL
SELECT 'no_key_set' val,
       count(distinct(userid)) uniqs
FROM all_rows a1 LEFT ANTI JOIN 
     all_rows a2 on (a1.userid = a2.userid and a2.has_key=1) 
GROUP BY val;

Results:

val        | uniqs
--------------------
vy         | 2
no_key_set | 2

我希望避免使用任何临时表,那么可以实现更好的方法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

通过使用EXPLAIN,您可以发现大部分费用都用于执行过多的GROUP BY聚合,而不是在原始查询中使用子查询。

这是一个简单的实现

WITH t1 AS (
    SELECT pkey, COUNT(*) AS cnt
    FROM table
    WHERE pkey IS NOT NULL
    GROUP BY pkey
), t2 AS (
    SELECT COUNT(DISTINCT userid) AS total_cnt
    FROM table
)
SELECT
    CONCAT('no_', pkey) AS pkey,
    (total_cnt - cnt) AS cnt
FROM t1, t2
UNION ALL
SELECT * FROM t1
  • t1获取每个pkey唯一用户数的表格

    +------+-----+
    | pkey | cnt |
    +------+-----+
    | x    | 1   |
    | z    | 2   |
    | y    | 2   |
    +------+-----+
    
  • t2获取唯一身份用户总数

    +-----------+
    | total_cnt |
    +-----------+
    | 4         |
    +-----------+
    
  • 我们可以使用t2的结果来获取t1

    的补码表
    +------+-----+
    | pkey | cnt |
    +------+-----+
    | no_x | 3   |
    | no_z | 2   |
    | no_y | 2   |
    +------+-----+
    
  • 两个表的最终并集给出了

    的结果
    +------+-----+
    | pkey | cnt |
    +------+-----+
    | no_x | 3   |
    | no_z | 2   |
    | no_y | 2   |
    | x    | 1   |
    | z    | 2   |
    | y    | 2   |
    +------+-----+