Рекомендации по сегментации по внешним данным
Сегментация по внешним источникам данных — полезный инструмент, но при неправильной настройке она может стать причиной значительного замедления работы сегментов. Ниже собраны рекомендации, которые помогут избежать типичных проблем с производительностью.
Минимизация объёма данных
Внешние источники данных следует проектировать так, чтобы они возвращали как можно меньше данных. Чем меньше записей платформа должна обработать, тем быстрее будет рассчитан сегмент.
Основные правила:
- Возвращайте только колонку с идентификатором профиля, по которому происходит поиск. Дополнительные колонки не нужны и только увеличивают объём передаваемых данных.
- По возможности добавляйте фильтрацию прямо в запрос или в URL API. Например, если вам нужны только активные клиенты, добавьте
WHERE is_active = 1в SQL-запрос. Это уменьшит объём данных, которые платформа получит от внешней базы, и ускорит расчёт сегмента. - Для HTTP-запросов к API — внешний сервис должен возвращать только список идентификаторов, а не полные объекты с дополнительными полями.
- Для загружаемых файлов — файл должен содержать только нужную колонку с идентификаторами.
- Используйте параметр кэширования результата при создании SQL-запроса сегментации. Если данные меняются редко, кэширование значительно ускорит повторные расчёты сегмента.
Объединение условий в одном SQL-запросе
Когда вам нужно отфильтровать профили по нескольким условиям из одной внешней SQL-базы, лучше написать один запрос с объединёнными условиями, чем создавать несколько запросов и соединять их в сегменте через "И".
Каждый отдельный запрос сегментации — это отдельное обращение к внешней базе. Чем больше запросов, тем дольше расчёт сегмента.
Пример. Представьте, что вам нужно выбрать клиентов, у которых есть активный договор и которые находятся в нужном регионе.
Неэффективный вариант — два отдельных запроса сегментации:
- Запрос "Договоры":
SELECT id FROM contracts WHERE status = 'active' - Запрос "Регионы":
SELECT id FROM customers WHERE region = 'Moscow'
Затем в сегменте эти два условия соединены через "И":
В таблице данных (запрос "Договоры")
И
В таблице данных (запрос "Регионы")
Платформа выполнит два отдельных запроса к базе, получит два списка идентификаторов и пересечёт их внутри себя.
Эффективный вариант — один запрос сегментации с объединёнными условиями:
SELECT customers.id
FROM contracts
JOIN customers ON customers.id = contracts.customer_id
WHERE contracts.status = 'active' AND customers.region = 'Moscow'
В сегменте — одно условие:
В таблице данных (запрос "Договоры и регионы")
Платформа выполнит один запрос, и пересечение произойдёт на стороне базы данных — это быстрее.
Рекомендации:
- Если условия относятся к одной внешней базе — объединяйте их в один SQL-запрос с помощью JOIN, подзапросов или UNION.
- Если условия относятся к разным базам — объединить их в один запрос невозможно, и платформа выполнит их последовательно. В этом случае постарайтесь, чтобы каждый запрос возвращал как можно меньше записей.
- Используйте параметры запросов, чтобы сделать один универсальный запрос вместо нескольких похожих. Например, один запрос с параметром
{REGION}лучше, чем отдельные запросы для каждого региона. - Старайтесь, чтобы все запросы в сегменте обращались к одному полю профиля (например,
customer_id). Платформа может автоматически объединять запросы только если они привязаны к одному и тому же полю профиля и используют один коннектор.
Автоматическое объединение запросов
В платформе реализована оптимизация, которая позволяет объединять несколько запросов сегментации к одной внешней базе в единый SQL-запрос. Вместо того чтобы выполнять каждый запрос отдельно, выгружать результаты и пересекать их внутри платформы, платформа формирует один запрос с операциями INTERSECT (пересечение), UNION (объединение) или EXCEPT (исключение) — и выполняет его на стороне внешней базы.
Как это работает. Если в сегменте есть несколько условий "В таблице данных", которые обращаются к одному коннектору и привязаны к одному и тому же полю профиля, платформа может объединить их:
В таблице данных (запрос "Договоры")
И
В таблице данных (запрос "Регионы")
Вместо двух отдельных запросов платформа сформирует один:
(SELECT id FROM query1) INTERSECT (SELECT id FROM query2)
Если одно из условий — "Не в таблице данных", платформа использует EXCEPT:
(SELECT id FROM query1) EXCEPT (SELECT id FROM query2)
Оптимизация включается администратором платформы (параметр SEGMENT_SQL_DATA_GROUP_OPTIMIZATION). Подробнее в документации администратора.
Ограничения:
- Объединяются только запросы одного коннектора и одного поля профиля.
- Если между запросами есть другие условия сегмента (не по внешней базе), объединение может не сработать. Например, конструкция вида
Запрос И (Запрос ИЛИ Условие)не может быть объединена, потому что не-запросное условие "разрывает" группу.