временными рядами с несколькими метриками. Эти метрики будут агрегироваться по временным интервалам.
                  
                  
                  Какая архитектура таблицы будет быстрее обрабатывать запрос на агрегацию?
                  
                  
                  Варианты таблиц и запросов:
                  
                  
                  1. 
                  
                  
                  CREATE TABLE table
                  
                  
                  ( 
                  
                  
                      id                   UInt32, 
                  
                  
                      timecode     DateTime,
                  
                  
                      metric_1       Float32,
                  
                  
                      metric_2       Float32,
                  
                  
                      metric_3       Float32
                  
                  
                  ) 
                  
                  
                      ENGINE = MergeTree() 
                  
                  
                          PARTITION BY toYYYYMM(timecode) 
                  
                  
                          ORDER BY (id, timecode);
                  
                  
                  
                  
                  
                  SELECT id, 
                  
                  
                                 toStartOfInterval(timecode, toIntervalMinute(30)) AS timecode_, 
                  
                  
                                 avg(metric_1) AS metric_1, 
                  
                  
                                 avg(metric_2) AS metric_2, 
                  
                  
                                 avg(metric_3) AS metric_3
                  
                  
                  FROM table 
                  
                  
                  GROUP BY id, timecode_;
                  
                  
                  —————————————————————-
                  
                  
                  2.
                  
                  
                  CREATE TABLE table
                  
                  
                  ( 
                  
                  
                      id                   UInt32,
                  
                  
                      metric_id     UInt16, 
                  
                  
                      timecode     DateTime,
                  
                  
                      value             Float32
                  
                  
                  ) 
                  
                  
                      ENGINE = MergeTree() 
                  
                  
                          PARTITION BY toYYYYMM(timecode) 
                  
                  
                          ORDER BY (id, metric_id, timecode);
                  
                  
                  
                  
                  
                  SELECT id, 
                  
                  
                                metric_id
                  
                  
                                toStartOfInterval(timecode, toIntervalMinute(30)) AS timecode_, 
                  
                  
                                avg(value) AS value
                  
                  
                  FROM table 
                  
                  
                  GROUP BY id, metric_id, timecode_;
                  
                  
                  ——————————————————————————————
                  
                  
                  Интуитивно, 2 вариант должен быть быстрее, но есть сомнения.
                  
                  
                
Во втором варианте больше бакетов. Обычно это плохо. Но в первом размер бакета больше. Так что лучше проверить на ваших данных. Так-же решение зависит от доступной RAM и состояния optimize_aggregation_in_order. Очень странно что у вас нет WHERE. Вы правда всю таблицу читаете и аггрегируете?
WHERE обязательно будет, я убрал его из примера.
А зря. Это самый важный вопрос при выборе ORDER BY таблицы. Для GROUP BY запросов это не столь важно (особенно если вы не используете optimize_aggregation_in_order)
Было предположение, что во втором случае данные на диске хранятся ближе, а значит их чтение должно быть быстрее.
а это предположение верное, или я заблуждаюсь?
Я же говорю, все эти предположения имеют смысл только в контексте WHERE. Так как вы показали - все равно. 100% данных будет считано из таблицы для агрегации. Еще можно подискутировать про уровень компрессии, для близкорасположенных данных при разных вариантах ORDER BY, но тут снова проще измерить на реальных.
Обсуждают сегодня