Более быстрый способ изменения структуры массива в Clickhouse

Мне интересно, есть ли более быстрый способ сделать то, что я пытаюсь сделать ниже, - в основном, отключить массив и создать groupArray с разными столбцами.

-- create table

CREATE TABLE default.t15 ( product String,  indx Array(UInt8),  col1 String,  col2 Array(UInt8)) ENGINE = Memory ;

--insert values

INSERT into t15 values ('p',[1,2,3],'a',[10,20,30]),('p',[1,2,3],'b',[40,50,60]),('p',[1,2,3],'c',[70,80,90]);

-- select values
    SELECT * from t15;

┌─product─┬─indx────┬─col1─┬─col2───────┐
│ p       │ [1,2,3] │ a    │ [10,20,30] │
│ p       │ [1,2,3] │ b    │ [40,50,60] │
│ p       │ [1,2,3] │ c    │ [70,80,90] │
└─────────┴─────────┴──────┴────────────┘

Желаемый результат

┌─product─┬─indx_list─┬─col1_arr──────┬─col2_arr───┐
│ p       │         1 │ ['a','b','c'] │ [10,40,70] │
│ p       │         2 │ ['a','b','c'] │ [20,50,80] │
│ p       │         3 │ ['a','b','c'] │ [30,60,90] │
└─────────┴───────────┴───────────────┴────────────┘

Как я это делаю -> [немного медленно, для чего мне это нужно]

SELECT   product, 
         indx_list, 
         groupArray(col1)      col1_arr, 
         groupArray(col2_list) col2_arr 
FROM     ( 
                  SELECT   product, 
                           indx_list, 
                           col1, 
                           col2_list 
                  FROM     t15 
                  ARRAY JOIN
                           indx AS indx_list, 
                           col2 AS col2_list 
                  ORDER BY indx_list, 
                           col1
          )x 
GROUP BY product, 
         indx_list;

По сути, я отключаю массив, а затем группирую его обратно. Есть ли лучший и более быстрый способ сделать это?

Спасибо!


person calgs    schedule 04.01.2019    source источник


Ответы (2)


Если вы хотите сделать это быстрее, похоже, что вы можете избежать подвыбора и глобального ORDER BY в нем. Так что-то вроде:

SELECT 
    product, 
    indx_list, 
    groupArray(col1) AS col1_arr, 
    groupArray(col2_list) AS col2_arr
FROM t15 
ARRAY JOIN 
    indx AS indx_list, 
    col2 AS col2_list
GROUP BY 
    product, 
    indx_list

Если вам нужно отсортировать массивы, обычно лучше сортировать их внутри каждой группы отдельно, используя arraySort.

person filimonov    schedule 04.02.2019

Я бы сделал запрос немного проще, чтобы уменьшить количество объединений массива до одного, что, вероятно, повысит производительность:

SELECT
    product,
    index as indx_list,
    groupArray(col1) as col1_arr,
    groupArray(element) as col2_arr
FROM
(
    SELECT
        product,
        arrayJoin(indx) AS index,
        col1,
        col2[index] AS element
    FROM default.t15
)
GROUP BY
    product,
    index;

Возможно, имеет смысл изменить структуру таблицы, чтобы избавиться от любых массивов. Я бы предложил плоскую схему:

CREATE TABLE default.t15 ( 
  product String,  
  valueId UInt8,  /* indx */
  col1 String, /* col1 */
  value UInt8) /* col2 */
  ENGINE = Memory ;
person vladimir    schedule 09.01.2019