Индексиранный вид для агрегации метрик

Microsoft Azure SQL – это мощная, полностью управляемая платформа баз данных, разработанная для высокопроизводительных запросов, хранения реляционных данных и аналитики. Для типичного веб-приложения с бэкендом это хороший выбор, когда мы хотим использовать управляемую базу данных, которая может масштабироваться как вертикально, так и горизонтально.

Приложение генерирует метрики пользователей ежедневно, которые могут быть использованы для отчетов или аналитики. Azure SQL – отличный выбор для хранения и запросов этих данных при определенных условиях:

  1. Аналитические запросы требуют объединения с другими таблицами (применение фильтров на пользовательском интерфейсе)
  2. Вы хотите объединить исторические и транзакционные данные
  3. Объем данных не очень большой, и производительность запросов может быть управляема путем настройки

Рассмотрим пример сайта бронирования отелей, работающего на Azure SQL на бэкенде. Мы хотим увидеть панель управления пользовательской активностью, такую как клики на сайте, посещения страницы с описанием отеля, сделанные бронирования и т. д.

Допустим, все данные телеметрии сбрасываются для каждого пользователя ежедневно в неструктурированное хранилище, и мы извлекаем эти данные в нашу базу данных с помощью фоновых задач, таких как Apache Airflow.

Ниже приведена схема таблицы пользователей и таблицы для хранения ежедневных метрик.

MS SQL

 

Из вышеперечисленных таблиц можно извлечь много полезной информации.

Давайте рассмотрим один конкретный пример. Нам нужно агрегировать ежедневные метрики активности, сгруппированные по дате в порядке убывания для клиентов в возрасте от 30 до 40 лет, находящихся в Нью-Йорке. Ниже приведен запрос:

MS SQL

 

Теперь мы можем проанализировать ежедневные тенденции в этой группе пользователей, которые находятся в Нью-Йорке и в возрасте от 30 до 40 лет. Таблица в основном работает быстро, и мы легко можем выполнять диапазонные запросы, охватывающие несколько месяцев. В конечном итоге наши требования растут. Теперь мы хотим отслеживать поведение пользователей в недельном или месячном диапазоне. Но наша таблица хранит данные ежедневно. Теперь у нас есть два варианта:

  • Запросить таблицу и сгруппировать date_created еженедельно или ежемесячно, в зависимости от запроса.
  • Создать несколько представлений, которые агрегируют данные еженедельно или ежемесячно для каждого пользователя. См. запрос ниже:
MS SQL

 

Однако важно учитывать, что представления просто предоставляют абстракцию к базовому запросу, который просто запрашивает данные из базовой таблицы. Материализованные представления – следующая мысль, которая приходит на ум. Однако их необходимо обновлять вручную или по расписанию, из-за чего реальные данные не доступны в реальном времени.

Чтобы решить эти проблемы, Azure SQL Server предлагает отличную функцию, известную как Индексированный Вид.  Янексированный Вид — это физическое представление вида, хранящееся в базе данных с уникальным кластерным индексом. Изменения в подлежащих таблицах автоматически обновляют индексированный вид, чтобы поддерживать его синхронизацию. Он использует кластерный индекс, который организует данные в виде на основе порядка ключей индекса.

Индексированный вид идеально подходит для сценариев, где нам нужны данные в реальном времени, а наш запрос включает сложные соединения нескольких таблиц. Он также подходит для нашего случая, когда существующие данные редко обновляются, но часто запрашиваются, и у нас есть запросы на основе диапазона и необходимость упорядоченного извлечения.

Существует несколько моментов, которые следует учитывать, прежде чем решать, хотите ли вы использовать индексированные виды. Индексированные виды не могут содержать недетерминированные функции. Недетерминированнаяфункция — это функция, которая не всегда возвращает один и тот же результат для одного и того же входа, даже если она выполняется с идентичными аргументами и в одних и тех же условиях базы данных. Кроме того, индексированный вид является фактической структурой, требующей хранения, аналогично Материализованному Виду.

Синтаксис для создания Индексированного Вида похож на запрос на создание Вида, приведенный выше. Однако мы не можем использовать недетерминированные функции при создании индексированного вида. Строка DATEADD(DAY, -(DATEPART(WEEKDAY, date) - 1), date) AS week_start в запросе вида выше зависит от специфической для сеанса настройки SET DATEFIRST, которая определяет первый день недели. Это считается недетерминированным, так как будет давать разные результаты в различных условиях.

Имея в виду вышеизложенное, мы можем приступить к устранению недетерминированных вычислений, сделав столбец детерминированным. Мы добавляем столбец week_start к базовой таблице, предварительно вычисляем и заполняем значение week_start в таблице для ежедневного извлечения данных. Таким образом, строки с датами D1 по D7 принадлежат W1, с D8 по D14 – W2 и так далее.

Теперь мы можем приступить к созданию индексированного представления с помощью следующего SQL-кода.

MS SQL

 

После создания этого индексированного представления, мы можем запрашивать его следующим образом:

MS SQL

 

Заключение

Индексированное представление будет иметь значительно более быстрое время запроса, чем обычное представление или запрос к таблице напрямую для больших наборов данных, где данные выросли до миллиона строк или более. Конечный пользователь получит низкую задержку, и запросы к базе данных будут оптимизированы. Поскольку мы агрегировали данные за неделю в 1 строку, мы сократили время агрегации до 1/7.

Source:
https://dzone.com/articles/indexed-view-for-aggregating-metrics