Возможно ли в SQL масштабное аналитическое исследование?

Развенчиваем мифы о недостатках SQL по сравнению с Python

Posted by Ekaterina on May 20, 2022

Некоторые коллеги полагают, что SQL подходит лишь для получения данных из хранилища, первичной обработки и агрегации данных, но не для полноценной аналитики. При большом количестве связанных таблиц код получается громоздким, при этом ничего кроме описательных статистик (и то неполных) получить нельзя.  

Мы считаем, что это не так. Почему? 

Два подхода к аналитике 

В очень многих проектах используется ORM (object-relational mapping). Пишется код, который пытается произвести расчеты на основании объектов и классов. 

Либо пишется код (обычно на Python), который имеет доступ напрямую к БД и анализирует данные оттуда. 

Второй подход более эффективен. Почему? 

 

  • У всех ORM очень сложная структура. То есть расчеты через ORM часто не сходятся с прототипами и контринтуитивны. Например, минимум оказывается совсем не таким, как вы ожидали. 
  • В каждом языке у ORM свои особенности. 
  • Если хранилище очень объемное, возникают серьезные сомнения по поводу качества данных, их подготовки, нулевых значений, ошибок в данных и пр. Насколько все это учитывается в коде – большой вопрос.

 

Второй подход – через скрипты к базе – реализуется обычно через Python, но там агрегация таблиц довольно неудобна. Если, например, у вас строковая БД со столбцовым хранением, то в Python будет непросто развернуть эти данные в необходимые датафреймы. Обычно это кортежи: ключ, значение и ключ на другую таблицу. В Python такие связи даются довольно сложно. 

Аналитика в Python удобна тогда, когда у вас нормализованные связанные таблицы с ID и нормальное строковое хранение – таблицы типа Excel, просто большие. Но вы можете сделать выбор в пользу R, потому что R в ряде случаев работает быстрее, чем Python. 

На самом деле, когда аналитика должна осуществляться системно, часто кроме SQL вариантов мало. Если вам нужно считать статистику раз в неделю, раз в день, ночью, давать ее пользователю, делать бизнес-метрики или принимать бизнес-решения на ее основе, то решение на Python получится очень хрупким. 

Громоздкий код

Что касается мнения о громоздкости кода при большом количестве связанных таблиц – Postgres, например, поддерживает разные схемы. Вы всегда можете сделать предагрегацию, материализованные представления и уже из них «дергать» данные. 

С другой стороны, 20 таблиц – это 20 Left Join. Единственное – нужно в них не ошибиться, чтобы строки не дублировались: это сильно влияет на качество статистики. Самая большая сложность не в длине кода, а в проверке, нет ли в SQL-запросе ошибки, которая приведет к ошибке в расчетах. Поэтому нельзя сказать, что здесь на первом месте громоздкость – скорее качество кода.  

Для таких расчетов мы делаем Excel-прототип, потом сверяем с ним расчеты на нескольких примерах. Excel-прототипирование в этих случаях бесценно – и очень сложно. При сложной статистике полноценный Excel-прототип занимает несколько дней или даже недель. Но эти прототипы мы потом используем как документацию к коду. Когда код действительно очень большой (у нас есть хранимые процедуры на несколько тысяч строк), бывает трудно понять, что происходит. Мы возвращаемся к Excel-прототипу и смотрим те или иные концепции именно там.

Аналитика здравого смысла 

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

Но на самом деле большинство потребностей бизнеса – это аналитика здравого смысла. Это не Machine Learning, а поиск ответа на вопрос: «Что будет, если цену поднять на 2%, а количество товара уменьшить на 3%?» (и сделать это вчера). 

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