Фатальный пример, который будет вычисляться вечность
Это не придуманный пример. Это кулстори о том, как началось моё знакомство с обработкой данных 6 лет назад.
❓ Задача: взять данные из одной таблицы и отфильтровать в ней данные из другой таблицы.
Решение от сверхразума (НЕ НАДО ТАК ДЕЛАТЬ):
1️⃣ К текущей Таблице 1 — небольшой выгрузке данных из рекламного кабинета со всеми возможными атрибутами и метриками и детализацией до дат:
500.000 строк * 30 столбцов = 15.000.000 ячеек
Присоединяем Таблицу 2:
10.000 строк * 10 столбцов = 100.000 ячеек
2️⃣ Потом отсортируем строки.
3️⃣ Потом отфильтруем строки по ряду условий.
4️⃣ Потом создаем новые столбцы, что инициирует создание копии целой таблицы.
Но из-за незнания матчасти к чему приводит именно такой порядок действий:
1️⃣ Сначала в Таблице 1 создаем новый столбец. Тем сам записывая в память всю таблицу целиком, т.к. каждая операция Table.AddColumn создаёт в памяти копию всей исходной таблицы.
2️⃣ В новом столбце Таблицы 1 ссылаемся в каждой ячейке на целиком всю Таблицу 2. Тем самым создав столько же копий Таблицы 2, сколько строк в Таблице 1.
Только за сам факт того, что объединение таблиц выполняется таким зверским садистским для процессора способом, уже нужно отрубать руки и публично пинать ссаными тряпками.
3️⃣ Разворачиваем Таблицу 2 целиком, тем самым умножив друг на друга количество строк из Таблицы 1 на количество строк из Таблицы 2:
500.000 строк * 10.000 строк = 5 млрд строк
А также расширили объединённую таблицу на количество столбцов из Таблицы 2:
5 млрд строк * (30 + 10 столбцов) = 200 млрд ячеек
Теперь в объединённой таблице 200 миллиардов ячеек.
4️⃣ И этот массив мы еще дальше собираемся:
➕ Сортировать.
➕ Фильтровать.
➕ Добавлять несколько новых столбцов — каждая вызванная функция Table.AddColumn создает в памяти копию целиком всей объединённой таблицы из 200 млрд ячеек с каждого предыдущего шага.
Нетрудно догадаться, что после перемножения таблиц каждая из последующих операций вызовет во столько же раз больше вычислений, во сколько раз выше стала Таблица 1, будучи умноженной по вертикали на количество строк из Таблицы 2.
Накинем сюда ещё и то, что чем больше столбцов в любом обрабатываемом массиве, тем дольше отрабатывает каждый шаг.
При присоединении и разворачивании целиком всех столбцов из Таблицы 2, в которой было 10 столбцов, ради того, чтобы, например, оставить в итоге 1–2 столбца, общее количество вычислений при дальнейших сортировках и фильтрациях будет рассчитываться не только умножением строк из Таблицы 1 на количество строк из Таблицы 2, а ещё теперь и на общее количество столбцов в объединённой таблице.
Вот откуда берутся долго работающие запросы.
Вот откуда растут ноги у проблемы.
В каком порядке оптимальнее и быстрее обрабатывать данные для возможности масштабирования алгоритма его вычислений на объёмах данных, во много раз превышающих размеры вашего текущего или тестового датасета — в следующем посте.
via @ppc_bigbrain
Предыдущие посты серии:
1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.
4. Оптимизация кода.
5. Если код не "летает".
6. Минимизируем вычисления.
Это не придуманный пример. Это кулстори о том, как началось моё знакомство с обработкой данных 6 лет назад.
❓ Задача: взять данные из одной таблицы и отфильтровать в ней данные из другой таблицы.
Решение от сверхразума (НЕ НАДО ТАК ДЕЛАТЬ):
1️⃣ К текущей Таблице 1 — небольшой выгрузке данных из рекламного кабинета со всеми возможными атрибутами и метриками и детализацией до дат:
500.000 строк * 30 столбцов = 15.000.000 ячеек
Присоединяем Таблицу 2:
10.000 строк * 10 столбцов = 100.000 ячеек
2️⃣ Потом отсортируем строки.
3️⃣ Потом отфильтруем строки по ряду условий.
4️⃣ Потом создаем новые столбцы, что инициирует создание копии целой таблицы.
Но из-за незнания матчасти к чему приводит именно такой порядок действий:
1️⃣ Сначала в Таблице 1 создаем новый столбец. Тем сам записывая в память всю таблицу целиком, т.к. каждая операция Table.AddColumn создаёт в памяти копию всей исходной таблицы.
2️⃣ В новом столбце Таблицы 1 ссылаемся в каждой ячейке на целиком всю Таблицу 2. Тем самым создав столько же копий Таблицы 2, сколько строк в Таблице 1.
Только за сам факт того, что объединение таблиц выполняется таким зверским садистским для процессора способом, уже нужно отрубать руки и публично пинать ссаными тряпками.
3️⃣ Разворачиваем Таблицу 2 целиком, тем самым умножив друг на друга количество строк из Таблицы 1 на количество строк из Таблицы 2:
500.000 строк * 10.000 строк = 5 млрд строк
А также расширили объединённую таблицу на количество столбцов из Таблицы 2:
5 млрд строк * (30 + 10 столбцов) = 200 млрд ячеек
Теперь в объединённой таблице 200 миллиардов ячеек.
4️⃣ И этот массив мы еще дальше собираемся:
➕ Сортировать.
➕ Фильтровать.
➕ Добавлять несколько новых столбцов — каждая вызванная функция Table.AddColumn создает в памяти копию целиком всей объединённой таблицы из 200 млрд ячеек с каждого предыдущего шага.
Нетрудно догадаться, что после перемножения таблиц каждая из последующих операций вызовет во столько же раз больше вычислений, во сколько раз выше стала Таблица 1, будучи умноженной по вертикали на количество строк из Таблицы 2.
Накинем сюда ещё и то, что чем больше столбцов в любом обрабатываемом массиве, тем дольше отрабатывает каждый шаг.
При присоединении и разворачивании целиком всех столбцов из Таблицы 2, в которой было 10 столбцов, ради того, чтобы, например, оставить в итоге 1–2 столбца, общее количество вычислений при дальнейших сортировках и фильтрациях будет рассчитываться не только умножением строк из Таблицы 1 на количество строк из Таблицы 2, а ещё теперь и на общее количество столбцов в объединённой таблице.
Вот откуда берутся долго работающие запросы.
Вот откуда растут ноги у проблемы.
Надо ли добавить очевидное, что спустя сутки ожидания я так и не дождался обработки этого запроса 6 лет назад? А ждал бы до сих пор.
В каком порядке оптимальнее и быстрее обрабатывать данные для возможности масштабирования алгоритма его вычислений на объёмах данных, во много раз превышающих размеры вашего текущего или тестового датасета — в следующем посте.
via @ppc_bigbrain