fa
Feedback

فریب کلاهبرداران را نخورید! تل‌متریو این کانال‌ها را شناسایی و برچسب‌گذاری می‌کند 👉 برای مشاهده برچسب، اشتراک تهیه کنید

Greenplum secrets🎩

Greenplum secrets🎩

رفتن به کانال در Telegram

The channel about best practice coding for Greenplum / Канал о том как писать оптимальный код в Greenplum. by @smartyru

نمایش بیشتر
683
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-17 روز
+130 روز
آرشیو پست ها
В продолжение поста, пришло время задать самый творческий вопрос: Дело в том, что при пересоздании марта ( в другой схеме этой же БД ) план для неоптимального запроса поменялся, и он даже стал быстрее первого, в обоих вариантах появился бродкаст и планы почти сравнялись, разница только в методе join-а с журналом: Hash Semi-Join для IN фильтра и Hash Left Anti Semi (Not-In) Join для NOT IN фильтра . Интересно, как такое возможно, два марта идентичны, включая размер ( за исключением pg_class.relacl) но планы (вчерашний и сегодняшний) для них разные.
explain analyze
 SELECT count(*)
   FROM (datamart a
     JOIN ( SELECT b.agreement_rk,
            max(b.version_id) AS version_id
           FROM datamart b
          WHERE ((b.version_id IN ( SELECT version.version_id
                   FROM etl.version
                  WHERE ((version.processed_flg IS TRUE)))))
          GROUP BY b.agreement_rk 
         ) c USING (agreement_rk, version_id));

Секрет 45 (Когда Broadcast лучше Redistribute ) Друзья, т.к. ниженаписанное было мне неочевидно до сих пор, зафиксирую отдельным постом, твердо и четко! Старожилы канала, вероятно, помнят, что ранее у нас была заруба как лучше получить актуальный срез SCD2 таблицы (далее март), а также и то, что говорили о вреде NOT IN фильтра. На стыке этих тем родился наглядный пример, как можно написать неоптимальный запроc на ровном месте, если задача банально осложняется тем, что при отборе последних версий из марта надо проверять статус каждой версии (в отдельном журнале) , которая либо обработана ( processed_flg = TRUE ), либо - нет ( processed_flg = FALSE ). В идеале, хорошо, когда март и журнал обработки версий комитятся в одной транзакции, и тогда проверка статуса не нужна, но в зависимости от архитектуры решения, реализация может варьироваться. Рассмотрим кейс, когда записи комитятся в марте, после чего фиксируется их статус в отдельной таблице version в отдельной тарнзакции. Сразу дам оптимальный запрос, где отбираются только обработанные версии:
SELECT a.*
   FROM datamart a
     JOIN ( SELECT b.transaction_id,
            max(b.version_id) AS version_id
           FROM datamart b
          WHERE b.version_id IN ( SELECT version_id
                   FROM version
                  WHERE processed_flg IS TRUE)
          GROUP BY b.transaction_id) c USING (transaction_id, version_id)
Но вот если фильтр заменить казалось бы на эквивалентный, то запрос отработает кратно медленнее ( в нашем случае - x2, Карл! )
WHERE NOT (b.version_id IN ( SELECT version_id
         FROM version
        WHERE processed_flg IS FALSE ))
А почему ? Чтобы не утруждать вас планами запросов, озвучу суть. В первом запросе фильтрующее множество целых чисел
 
SELECT version.version_id FROM version
 WHERE version.processed_flg IS TRUE
тупо бродкастится на все сегменты как более дешевое решение (GPORCA в действии!), тогда как во втором - сам март перерраспределится по кластеру по полям оконки (transaction_id, version_id ) для последующего Anti-Join с журналом для фильтрации того, что уйдет на GROUP BY Очевидно, чем больше число полей в фильтрующей выборке с, состоящей из ключей последних версий, тем больше будет перекос между производительностью двух запросоов. Т.к. на одну версию обычно приходятся обычно от тысяч до млн строк, то случай, что Broadcast будет дороже Redistribute интереса не представляет.

На заметку Параметр gp_resource_group_bypass снимает ограничение на параллельное выполнение запросов в ресурсной группе. Этот параметр может быть установлен только на уровне сессии, и при включении он позволит запросам обходить ограничение на параллельное выполнение в РГ и выполняться немедленно. Note The gp_resource_group_bypass configuration parameter, enables or disables the resource group concurrency limit. This parameter may only be set at the session level, and when enabled will allow queries to bypass the CONCURRENCY limit for the resource group and run immediately.

Кто знает, у СБЕРА своя MPP или таки Greenplum ?

Друзья, 2026 год по восточному календарю — это год Красной Огненной Лошади, который начинается 17 февраля 2026 года и продлится до 5 февраля 2027-го, символизируя энергию, страсть, перемены и стремление к независимости. Так как среди нас есть любители и мастера по шахматам, давно собирался это сделать - в 9:11 PM (21.11 мск) приглашаю всех, у кого есть аккаунтк на личесс на турнир, код на вход - 777, катнем 7 раундов, чтобы успеть до курантов, https://lichess.org/swiss/FBQq3KT8

Дорогие друзья! Желаю всем нам в новом году, чтобы ни у кого ничего не заклинило и шло все как по маслу!

parse_etl_function_params.sql0.04 KB

#LEGO#фреймворк#парсинг динамического кода Друзья, сверстал последний пост в уходящем году, а возможно в принципе на канале. Меня очень занимает, если не вдохновляет, идея создания универсального фреймворка, в котором будут все возможные SQL трансформации, т.к. интуиция подсказывает, что их множество ограничено, хотя и велико. Вероятно, у многих, кто использует свой in-house фреймворк, основной набор трансформаций T1, T2, ..., Tn реализован на PL/pgSQL функциях, у каждой из которых есть параметры, задающие входную таблицу(-ы) С большой вероятностью, из этих лего деталек T(i) вы строите достаточно сложные PL/pgSQL функции F для наполнения целевых витрин, которые могут быть достаточно емкими по размеру, но построены по модульному принципу, т.е. представлены цепочкой трансформаций. А если так, то вполне вероятно, что рано или поздно возникнет задача миграции определенной области ХД, в которых используются F, на новый сервер. И вот тут, если скажем исходные данные для F лежат в слое RDV, встает вопрос, какие именно таблицы требуются для переносимого функционала. Я имею ввиду, что сценарий, когда надо восстановить из бэкапа ряд таблиц RDV, представляющих набор исходных данных для F, и выкатить поток с F на новом сервере, чтобы бесшовно переключиться на работу ХД в новом контуре - вполне жизненная задача, ибо миграция петабайтного ХД за один присест - задача практически невозможная как с технической точки зрения так и экономически нецелесообразная, обычно такого слона едят по частям. Ввиду того, что такая потребность в получении списка таблиц возникла у меня, я озаботился и написал парсер для генерации списка исходных таблиц, которые используются в произвольной функции, построенной на операторах фрейма. Повторюсь, что концептуально такая функция должна состоять из набора трансформаций T(i), представленных PL/pgSQL функциями с именованными параметрами. Конкретно в моем случае я ловил пару параметров p_in_schema и p_in_table, задающих входы операторов фреймворка исключая ad-hoc трансформацию, признаком которой является наличие параметра p_sql_text. Также, поддержал случай, когда название таблицы в p_in_table параметризовано, т.е. завязано на название переменной, значение которой объявлено либо в секции F declare, либо в ее основном блоке begin .. end. Из интересного, я бы отметил, что мой любимый DeepSeek сделал 30% работы, остальное допиливал сам. Особо пришлось повозиться с 2D массивами, т.к. надежды на то, что в 2D можно добавить 1D массив через array_append не оправдались.

Проблема 1 (gprestore issue) Бывает, требуется восстановить данеые из бэкапа по списку таблиц, но не в чистую БД, а в уже созданные чистые таблицы. Если это делают не одни руки, а команда, то все может пойти не так гладко, как ожидалось. Предположим, аналитик допустил ошибку, и передал в список на рестор лишнюю таблицу, или наоборот в БД нет какой-то подготовленной таблицы (или ее партиции) из списка. Оказывается, в этом случае в 6-ке утилита gprestore рухнет при первой же ошибке. Да, вы не ослышались, без использования ключа --on-error-continue - процесс восстановления прерывается при любой первой возникающей ошибке. ⁉️ Так в чем проблема - включили ключ и погнали ? ⚠️ А в том, что ключ этот имеет неожиданное поведение при работе с бекапсетами собранными с использованием --single-data-file и частичной вычиткой из оных. Иными словами, если из бэкапа в сотни TB надо восстановить скажем 30% из 1000 таблиц, при каждом падении gprestore будет его перечитывать полностью и это уже проблема, которая может растянуться на часы, дни и т.д.. По хорошему, если бы для каждой таблы в бэкапе знать офсет ее DDL скрипта от начала ( а значит прямой указатель на сами данные, которые по идее идут сразу после), то не пришлось бы перечитывать файл целиком. Собственно, так и работает gprestore без ключа, но до первого падения. 📌Решение: Согласно анонсу, в 6.29.1 данное недоразумение пофиксили, за что компании Аренадата +1 к карме! Если кто проверял, дайте шуму, дайте знать!

У вас есть in-house фреймворк для генерации ETL кода в DWH? Do you have an in-house framework for generating ETL code in DWH?
Anonymous voting

Интересно, в вашем ИТ есть собственный фреймворк для генерации SQL кода в ХД. Или каждый разработчик A пишет готовый к исполнению код с нуля, даже если он повторяет ту же трасформаацию, написанную другим разработчиком B, пусть и на других таблицах. Опрос ниже по такому поводу. I wonder if your IT department has its own framework for generating SQL code in the data warehouse. Or does each developer A write ready-made code from scratch, even if they're repeating the same transformation written by another developer B, albeit on different tables. The survey is below

Друзья, выручайте, может у кого то завалялся фильм "Босиком по мостовой" с Швайгером, раздайте, плз
Друзья, выручайте, может у кого то завалялся фильм "Босиком по мостовой" с Швайгером, раздайте, плз

Вопрос 8 А кто знает, можно ли в GP сохранить результат запроса, в двумерный массив, не прибегая к PL/pgSQL Does anyone know if it's possible to save the query result in a two-dimensional array in GP without using PL/pgSQL?
SQL> select regexp_matches('a := 1,b := 1', '(\w+)\s*:=\s*([^,]+)', 'g') as m
m
-----
{a,1}
{b,1}

А вы знали, что если в ватс апп сменить язык на болгарский то звонки работают без впн( хак от коллеги, не проверял пока)

Правильный ответ на опрос выше - 1(Да). Если в запросе есть сортировка ORDER BY, возможен спилл. Напомню, что в ITAS(CTAS - не суть) это может давать хороший выигрыш по месту, о чем писал неоднократно, напр. The correct answer to the poll above is 1.If the query contains an ORDER BY clause, a spill is possible. As a reminder, in ITAS(CTAS - no matter), this can yield significant space savings, as I've written about repeatedly, for example:

Операция ITAS (Insert table as select) из A в B может создать спилл ? // Can ITAS (Insert table as select) operation from A to B create a spill?
Anonymous voting

Ваш основной тул на работе в найме для ad-hoc расчетов // Your main tool as employee for ad-hoc calculations
Anonymous voting

В Лас-Вегасе стартовал финал чемпионата мира по Microsoft Excel. 24 финалиста в течение трёх дней решают сложные кейсы на вылет в легендарной HyperX Arena, где обычно соревнуются киберспортсмены. На кону рекордные $60 000 (4,7 млн рублей), а победитель получит чемпионский пояс в стиле WWE. The Microsoft Excel World Championship finals have kicked off in Las Vegas. Over three days, 24 finalists will solve challenging knockout cases at the legendary HyperX Arena, where esports athletes typically compete. A record-breaking $60,000 (4.7 million rubles) is at stake, and the winner will receive a WWE-style championship belt.

К секрету 26,ч.2
К секрету 26,ч.2

Оказалось, планы совпадают, а моя гипотеза несостоятельна. А дело вот в чем. Анализ плана (ниже фрагмент его критичных слайсов) дал следующий инсайд : На первом шаге идет также Broadcast справочника, который Hash Join-им с большой табл-ой под вью, и вот этот результат Oops.. снова Broadcast-им. Соотв-но, последний Broadcast для случая 1 строки в справочнике пересылает в 1500 строк меньше, чем для полного. Для 0 строк в справочнике последний Broadcast соотв-но просто номинальный шаг. Остается добавить, если выполнить исходный запрос на справочнике с собранной статой, запрос выполнился без спилла за 8.5 мин с ожидаемым Redistribute, но у меня и РГ другая, не такая крутая, как у регламентного потока на проме. Остается загадкой, а зачем нужен 2й Broadcast, кроме первого, который дал нам возможность сделать Hash-Join