Pull to refresh

Comments 7

А можно ли в PG/greenpulm указывать в запросах в секции from нужную секцию?

Например:

select * from table partition(act_prt) t where t.date_1 > sysdate - 1;

Да, конечно

Пример:
create table if not exists t (id int) partition by hash (id);

create table if not exists hash_p_1
partition of t for values with(modulus 2, remainder 1);

create table if not exists hash_p_0
partition of t for values with(modulus 2, remainder 0);
  
insert into t
	select *
	from generate_series(1,100);
	
select * 
from hash_p_1;

Добрый день! Для просмотра структуры определенной таблицы, можно сделать выборку из системного представления pg_catalog.pg_partitions 

SELECT  partitiontablename,  partitionname,  partitiontype,  partitionlevel,  partitionrankFROM pg_catalog.pg_partitionsWHERE schemaname = '<schema_name>'AND tablename = '<table_name>';

На одной спичке все прекрасно. Вопросы возникают когда спичек больше одной.

Случай 1. У нас 4 таблицы.

Table1 (ID_1 serial, Param1, Param2, ... , ParamN, ID_3, ID_2) Допустим 200Гб

Table2(ID_2 serial, Param1, Param2, ... , ParamN, ID_3) Допустим 200Гб

Table3(ID_3 serial, Param1, Param2, ... , ParamN) Допустим 200Гб

Table4(Date, Param1, Param2, ... , ParamN, ID_1) (огромная и секционирована например по Date помесячно) Допустим 400Гб.

При этом все ID не являющиеся serial updatable.

И система должна быcтро делать запросы типа

select *

from Table4 t4

inner join Table1 t1 on t1.ID_1 = t4.ID_1

inner join Table2 t2 on t2.ID_2 = t1.ID_2

inner join Table3 t3 on t3.ID_3 = t1.ID_3

where Date = Дата

and t2.ParamM = ParamM

and t3.ParamK = ParamK;

Вытекает три проблемы

  1. Если распределить все ровненько по serial а Table4 random. То данные круто лежат по всем сегментам. Но вот для джоина нужен броадкаст.

  2. Нет никакой гарантии, что распределение данных по ParamM будет равномерным.

  3. Нет никакой гарантии, что распределение данных в каждой секции Date по ParamM будет равномерным.

А запросы будут всякие разные со всеми возможными условиями по Param из всех таблиц. Вот какие рекомендации могут быть в такой простой но жизненной ситуации? Вот как будет работать броадкаст, он перегонит все данные отосвcюду восюда? Т.е. для каждой секции придут почти по 200Гб данных из Table1,2,3? И памяти такой джоин отожрет на каждой секции сколько?

Или я что-то не понимаю и данная база пригодна исключительно для хранения больших витрин с которых быстро можно поселектить простенький отчет без джоинов или с джоинами по маленьким справочникам?

Если распределить все ровненько по serial а Table4 random

Огромную партиционированную таблицу оставлять с random-дистрибуцией - плохая идея в любом случае. Стоит сделать суррогатный ключ и распределить таблицу по нему

Вот как будет работать броадкаст

При собранной статистике по всем таблицам броадкасты тут вряд ли случатся, будут Redistribute Motion
Правда может произойти Broadcast Motion данных из Table 4, если по условию where Date = Дата выберется небольшой объём данных (относительно объёмов Table 1 - Table 3) из одной партиции Table 4
Если вместо inner join в запросе будут left join, то и такой кейс для broadcast исключён

--
Худшее, что тут может произойти - перекосы (skew) в промежуточных джойнах, которые можно наглядно отловить с помощью explain analyze. Самый простой способ от них избавиться - разобрать многоэтажные джойны на последовательные операции и оптимизировать их по отдельности (фильтровать null, выбирать distinct значения ключей для джойна и т.д.). Greenplum может переварить портянки на 10+ джойнов, но это редко является оптимальной формой запроса.

Не очень понял как поможет разобрать джоины на более мелкие. Допустим у вас есть активные запросы с разными условиями на Params. И дальнейшей обработки. Ну грубо выбираются данные из Table1 на основании его Params А дальше это все соединяется с Table2-Tabl4. Т.е. как не крути, если Table1 распределена по ключу то даже если для одного запроса мы все оптимизируем, то 100 других будут с перекосами от единиц процентов до нескольких порядков.

Ну таблицы большие. Положим будет Redistribute Motion но таких запросов тысячи и работать одновременно будут десятки. Насколько это вообще оправдано и как это будет аффектить использование памяти?

Я понимаю что База выбирается под конкретную задачу. Но мир чутка изменился. Предположим что задача вот как я описал, и база выбирается Greenplum, потому что. Забываем про стоимость системы и т.д. Насколько производительней будет система если Table1, Table2, Table3 replicated, а Table4 распределена случайно?

Ну правда жизни такова, что в больших DWH пользователей принято бить ногами за плохие запросы))
Вспоминая навскидку несколько примеров с конференций, в Авито, кажется, запросы рядовых пользователей вроде перехватывает парсер, проверяет план и не пропускает вопиющие косяки. В Тинькофф похожий сервис имеет говорящее имя "Инквизитор".
И это не только Greenplum касается, а вообще всех крупных хранилищ. Слышал про кейсы, когда за плохие запросы в Snowflake в AWS аналитиков наказывали долларом (т.к. там непосредственную цену каждого запроса легко посчитать).

Возвращаясь к таблицам:
При рандомной дистрибуции мы просто всегда будем получать Redistribute / Broadcast Motion и никогда не получим пользы от Greenplum как от MPP. Это всё равно, что гонять запросы между репликами обычного (причём устаревшего PostgreSQL).
В идеальном мире надо стремиться выжимать из запросов максимум ситуаций, когда данные будут крутиться внутри одного слайса на отдельных сегментах, и только в конце собираться на мастере. Для этого нужны осмысленные с точки зрения бизнеса ключи дистрибуции.

Sign up to leave a comment.