Хорошее замечание, что стоить иметь в виду EF, тоже рассматриваю его как направление для улучшений пакета.
Как я понял - в статье про то, что нужен именно синтаксис как в DAX.
И также логика SUMMARIZECOLUMNS в DAX Power BI немного сложнее, чем группировка с агрегацией, если кратко, то для примера с группировкой по Product[ProductId] и Customer[CustomerId] даже используются 3 группировки: «исходная» (параметр метода) x => new {x.productId, x.customerId} и на её основе в DaxSharp получаются две другие группировки при помощи рефлексии x => x.productId и x => x.customerId — эти группировки для декартова произведения.
На основе data делаются расчеты выражений (с фильтрацией строк и групп) с исходной группировкой по x => new {x.productId, x.customerId} и пишутся в Dictionary с ключом productId, x.customerId, дальше на основе группировок из рефлексии x => x.productId и x => x.customerId делается перебор для декартова произведения при помощи вложенных итераторов, достаются и возвращаются результаты из подсчитанного Dictionary, реализуется логика первых N значений и т.д.
Т.е. в итоге наверно даже получается не столько похожий на DAX Power BI синтаксис (хотя синтаксис похож), но возможность получить результаты по DAX SUMMARIZECOLUMNS логике декартового произведения, но на C#.
Спасибо за вопрос и комментарий, да, действительно, этот пакет в первую очередь для DAX-подобной семантики в C#.
Кейс для 100 млн записей в таблице фактов и декартова произведения 1 млн × 1 млн — это больше egde кейс для проверки корректности имплементации («ничего не зависает») и производительность пакета на миллионах записей ниже, чем в движках СУБД. Единственное, похоже, что сопоставимый SQL для ClickHouse (без деталей плана выполнения запроса) может выглядеть так (в общем случае поля t1.a и t2.a могут быть и неключевыми в таблицах t1 и t2, поэтому добавляется группировка):
SELECT *
FROM
(
(SELECT number % 1000000 AS a
FROM numbers(100000000)
GROUP BY a)
) AS t1
JOIN
(
(SELECT number % 1000000 AS a
FROM numbers(100000000)
GROUP BY a)
) AS t2
ON 1 = 1
LIMIT 1000;
Такой запрос выполняется в ClickHouse уже примерно 2.2 секунды и пока не содержит агрегацию SUM, логику IF и других функций (ISBLANK), т.е. полный вариант запроса будет ещё дольше выполняться. Также если вместо numbers(100000000) для сравнения взять numbers(1000000), то время выполнения запроса будет около половины секунды, тоже можно сказать, что измеряется в секундах, а не миллисекундах.
С другой стороны, за счет отсутствия запроса к СУБД пакет DaxSharp быстрее для меньшего количества записей (в «таблице фактов» Sales и соответствующей переменной sales), но с ограничениями, т.е. если есть возможность пренебречь временем загрузки всей таблицы sales в .NET приложение, загруженная таблица sales содержит актуальные данные и т.д.
Например, DaxSharp быстрее для запросов с 0 записей в sales (т.к. нет запроса к СУБД), для 1, 10, 100 записей, для нескольких тысяч и, возможно, десятков, сотен тысяч записей в sales, в итоге производительность зависит от запроса, данных и т.д.
Также пакет DaxSharp может использоваться без СУБД, например, с данными из файла или из API.
Хороший вопрос, да, описано больше разделение ресурсов (ноды ClickHouse) средствами Hangfire, т.е. например, на CH1 не более 2 запросов, на CH2 — не более одного, и т.д.
Наверно описано больше не балансирование, а соблюдение ограничений для ресурсов, т.е. с предложенным подходом любое балансирование (которое также нужно имплементировать) будет валидным для ресурсов. Например, для CH1 не будет условно 3 запросов одновременно.
Выбор очереди (и по сути ClickHouse) при отправке тоже нужно имплементировать, это и будет формально балансирование. Например, можно для имплементации балансирования использовать информацию о работах в очередях через EnqueuedJobs и выбирать очередь с наименьшим количеством работ в ней, или простейший вариант балансирования — выбор случайной ноды ClickHouse, также может быть и другая логика балансирования с учетом настроек или приоритетов нод ClickHouse и т.д., т.е. описано только соблюдение ограничений на ресурсы средствами Hangfire
Наверно единого оптимального решения нет, если Hangfire уже используется и нет планов с него уходить, то можно и его более глубоко использовать.
Akka .NET интересен, но в нем нужно переходить на акторы, и он подходит для всего приложения. Выглядит так, что его удобно использовать для новых проектов, но для существующих требует время на переход.
Да, критерий Кохрена-Кокса удобен в частном случае, и может быть сложно и развернуть две версии одновременно, и встроить критерий в тесты-бенчмарки. Как вариант, критерий удобен для PR'ов. По поводу параллельного выполнения тестов-бенчмарков — да, ускоряет, но чтобы бенчмарки были актуальными (т.к. это не только тесты, а измеряется время выполнения и оно должно быть постоянным для одного и того же бенчмарка на одной и той же версии), машины должны быть «условно одинаковыми», тесты не должны влиять друг на друга и т.д. Т.е. при параллельном варианте если условно «раскидать по всем нодам», то и результаты с них могут быть трудно сопоставимыми.
Вы привели хороший и наглядный пример анализа одного конкретного запроса вручную после его выполнения. Действительно, если запрос один, и он оптимизируется вручную, есть возможность несколько раз его выполнить, посмотреть план выполнения запроса, логи и т.д. — кардинальности не нужны, но это частная задача.
В движке Visiology решается общая задача — оптимизация произвольного (не конкретного) SQL запроса до его выполнения (не после), и без дополнительных запросов к СУБД (например, для подсчета уникальных значений комбинации полей одной таблицы), и оптимизация «с первой попытки» (не после просмотра логов и выполнения, возможно, неоптимального запроса), в таком случае актуальны кардинальности.
А не проще сразу писать быстрые запросы, а тех, кто не умеет - увольнять?
В дашбордах Visiology поддерживается DAX, в чистом виде SQL не используется, поэтому все вопросы, связанные с SQL, ДанКо решает без участия пользователя.
Получается, "кто ж его посадит, он же памятник")
Справедливости ради, автоматическая генерация и оптимизация SQL запросов является более общей и сложной задачей по сравнению с частными случаями оптимизаций, поэтому наверно такой диссонанс) Ручная "человеческая" оптимизация SQL действительно может давать SQL, выполняющийся быстрее автоматически сгенерированного, но ручная оптимизация SQL всегда требует затрат рабочего времени, ресурсов и т.д., по сравнению с автоматической в ДанКо
Хорошие примеры оптимизаций, выполненные вручную, — да, они реализованы в ДанКо.
В дашбордах Visiology поддерживается DAX, в чистом виде SQL не используется, поэтому все вопросы, связанные с SQL, ДанКо решает без участия пользователя.
В ДанКо поддерживается как минимум два вида кэширования: частей SQL запроса, кеширование всего результата DAX запроса. Также ДанКо поддерживает множество оптимизаций, изменяющих структуру SQL запроса, с учетом особенностей плана выполнения запроса в ClickHouse, типов данных, кардинальностей использованных столбцов и других параметров.
Все справедливые замечания, и по логике запроса, и по плану выполнения запроса в ClickHouse. Про запрос «до оптимизации» изначально говорилось, что он синтетический и только для целей иллюстрации, ведь если сразу написать оптимальный запрос, то нечего будет оптимизировать. Плюс здесь рассматривается именно оптимизация за счет комбинаторов ClickHouse с учетом кардинальностей, но так, конечно, подразумевается, что, например, переписывание запроса вручную даст результат лучше.
Интересная статья, появился вопрос по поводу математического аппарата, а именно, например, векторного представления текста. Векторное представление текста и все эти критерии условно синусов/косинусов угла между векторами текста и векторами текстов и поискового запроса известны и применяются уже многие десятилетия (условно более двух десятилетий).
И наверно можно согласиться, что все поисковые системы (Google, Яндекс и т.д.) провалились в сфере искусственного интеллекта (используя эти векторы для текстов) и разгромно проиграли (хотя имели миллиарды долларов и огромное исходное преимущество) "гонку AI" нейросетям и результаты поиска через нейросети намного более качественные, чем поиск через векторы текстов, который используется многие десятилетия.
В связи с этим вопрос, если результаты классификации/кластеризации и т.д. и т.п. у нейросетей на голову выше, и векторные представления текста вдоль и поперек изучены, какие перспективы у векторных представлений, нужно ли в будущем сочетать векторный подход с нейросетями для более качественных результатов?
Да, согласен, соединять план и факт из разных таблиц по полю из календаря — хорошая идея.
Тем не менее часто встречается денормализованная таблица, хоть и можно от неё отказаться с точки зрения ETL и возможностей DAX. Денормализованная таблица может остаться, например, по следующим причинам: даже в рассмотренном примере можно условно выделить три таблицы (суммарные факты за месяц, планы за месяц, детальные факты) и в каждой таблице может быть некоторое количество столбцов для аналитики (пусть условно десятки столбцов), причем значительная часть или все столбцы могут совпадать для трех таблиц. Также могут быть и условно десятки или сотни мер для каждой таблицы, причем значительная часть мер разных таблиц могут быть совпадать с точностью до имен столбцов. В таком случае создание трех таблиц вместо одной денормализованной может увеличить производительность, но и кратно увеличить количество мер (для каждой новой таблицы нужно дублировать одни и те же меры, которые были в денормализованной таблице) и в этом смысле создать некоторые сложности.
То есть нормализованная схема данных в общем случае выглядит предпочтительнее и нет рекомендаций использовать денормализованную таблицу вместо нескольких таблиц, но выбор оптимального решения по схеме данных зависит от проекта. В статье рассмотрены кейсы, как быть в том случае, если уже выбрана и используется денормализованная таблица, и какие приемы работы с ней могут быть.
Да, в общем случае я имел в виду не только эмоции разработчиков и их отношение к технологиям, но больше настроения и планы лиц, принимающих решения, с учетом затрат человеко-часов, компетенций разработчиков, стратегии развития компании и т.д.
Здесь это больше утилита, которая может облегчить жизнь аналитику при исследовании меры на неизвестной схеме данных. Например, у аналитика нет прав доступа к схеме данных, на которой построена мера, есть только текст меры, пришел вопрос по мере и нужно найти ошибку или что-то доработать в мере.
В таком случае аналитику можно просто вставить текст меры в утилиту и уже сразу как-то сориентироваться в мере, посмотреть на использованные таблицы с тестовыми данными, на примерные результаты, на запрос DAX с SUMMARIZECOLUMNS, на примерный вид дашборда с мерой.
Конечно, этого может быть недостаточно, тогда возможный следующий шаг — это создать схему данных из меры, при этом можно использовать сгенерированные утилитой тестовые данные и таблицы и загрузить их, например, из CSV. В этом может быть большой плюс утилиты, т.к. не нужно вручную печатать dummy данные для новой схемы. Альтернатива — переписать меру на другую схему данных (которая есть у аналитика) для более глубокого анализа, в таком случае утилита никак не может помочь (к слову, можно также перевести меру на другую схему данных также с помощью AI).
Если рассматривать DAX Visiology, то там есть и парсер, и AI чат-помощник ViTalk.
То есть, в запросе вообще нет JOIN, но он ужасно неэффективен
В статье нет цели заменить анализ плана выполнения запроса на один показатель. И даже если нет INNER JOIN — то такой кейс не является контрпримером, т.к. ноль INNER JOIN соответствует не оптимальности запроса, а только тому, что нет информации об ухудшении производительности запроса в разрезе INNER JOIN, а по другим критериям — по плану выполения запроса, или, в частности, по подзапросам и WHERE с оконными функциями — ухудшение производительности может быть.
В качестве дополнительной метрики можно использовать количество подзапросов (считать WITH), или при помощи регулярных выражений (при возможности и необходимости) искать как раз позапросы с WHERE и оконными функциями.
Вот уже из плана (постгрес умеет отдавать его во вполне разбираемом виде типа JSON или ямл) можно понять, эффективен ли запрос
В статье описывается подход применительно к тестам, не ставится задача глубокого анализа каждого SQL запроса, как может делать не только СУБД, но и, частично, например, какой-нибудь плагин Rider для разных SQL диалектов.
В контексте тестов всё фокусируется на оценке регресса, деградации, сравнении до и после, а не на детальном анализе запроса: если все SQL совпадают (определяем по совпадению двух Total хешей до и после), то деградации нет, тесты проходят и заканчиваем анализ. Делать выводы на основе нуля INNER JOIN при совпадении Total хешей всех запросов "до и после" никто не собирается.
попугаи на базе данных СУБД, а не выдумок
Всё же это не выдумки, а так как всё относится к тестам, то это больше идеи на основе эспертизы разработчика, что он делает, что меняет в генерации SQL, на что это может повлиять. Так вообще можно назвать любые тесты "выдумками" и их запретить.
Если разработчик видит, что он меняет логику генерации SQL, в которой присутствуют INNER JOIN, и он может случайно увеличить их количество, и это будет считаться багом и проблемой производительности, то в таком случае есть смысл считать количество INNER JOIN, записывать в таблицу, это не более чем метаданные для простейших тестов, упрощающие работу разработчика и позволяющие сразу найти и исправить такого рода баги: был 1 INNER JOIN, стало 2 или 10 — это выглядит, как явный баг, при изменениях в логике с INNER JOIN, и нуждается в проверке и исправлении, как раз с помощью ручного анализа плана выполнения запроса.
Но в подходе из статьи анализировать вручную требуется условно не все подряд 5000 тестов в проекте, а с учетом того, что изменения в SQL тестов фиксируются, вручную необходимо проверять только несколько тестов с именениями в SQL, плюс разработчик может и без анализа плана выполнения запроса понять, что +10 INNER JOIN — это баг, и сразу перейти к исправлению, тогда анализ плана заведомо неоптимального запроса и потерю времени на это можно исключить. Причем интеграционные тесты такие баги могут не выявить, т.к. результаты запросов могут совпасть, но SQL будет разный. То же самое и с другой метрикой, например, количеством подзапросов WITH, с несколькими метриками одновременно, и т.д.
Хорошее замечание, что стоить иметь в виду EF, тоже рассматриваю его как направление для улучшений пакета.
И также логика
SUMMARIZECOLUMNS
в DAX Power BI немного сложнее, чем группировка с агрегацией, если кратко, то для примера с группировкой поProduct[ProductId]
иCustomer[CustomerId]
даже используются 3 группировки: «исходная» (параметр метода)x =>
new
{x.productId, x.customerId}
и на её основе в DaxSharp получаются две другие группировки при помощи рефлексииx => x.productId
иx => x.customerId
— эти группировки для декартова произведения.На основе
data
делаются расчеты выражений (с фильтрацией строк и групп) с исходной группировкой поx =>
new
{x.productId, x.customerId}
и пишутся вDictionary
с ключомproductId, x.customerId
, дальше на основе группировок из рефлексииx => x.productId
иx => x.customerId
делается перебор для декартова произведения при помощи вложенных итераторов, достаются и возвращаются результаты из подсчитанногоDictionary
, реализуется логика первыхN
значений и т.д.Т.е. в итоге наверно даже получается не столько похожий на DAX Power BI синтаксис (хотя синтаксис похож), но возможность получить результаты по DAX
SUMMARIZECOLUMNS
логике декартового произведения, но на C#.Спасибо за вопрос и комментарий, да, действительно, этот пакет в первую очередь для DAX-подобной семантики в C#.
Кейс для 100 млн записей в таблице фактов и декартова произведения 1 млн × 1 млн — это больше egde кейс для проверки корректности имплементации («ничего не зависает») и производительность пакета на миллионах записей ниже, чем в движках СУБД. Единственное, похоже, что сопоставимый SQL для ClickHouse (без деталей плана выполнения запроса) может выглядеть так (в общем случае поля
t1.a
иt2.a
могут быть и неключевыми в таблицахt1
иt2
, поэтому добавляется группировка):Такой запрос выполняется в ClickHouse уже примерно 2.2 секунды и пока не содержит агрегацию
SUM
, логикуIF
и других функций (ISBLANK
), т.е. полный вариант запроса будет ещё дольше выполняться. Также если вместоnumbers(100000000)
для сравнения взятьnumbers(1000000)
, то время выполнения запроса будет около половины секунды, тоже можно сказать, что измеряется в секундах, а не миллисекундах.С другой стороны, за счет отсутствия запроса к СУБД пакет DaxSharp быстрее для меньшего количества записей (в «таблице фактов»
Sales
и соответствующей переменнойsales
), но с ограничениями, т.е. если есть возможность пренебречь временем загрузки всей таблицыsales
в .NET приложение, загруженная таблицаsales
содержит актуальные данные и т.д.Например, DaxSharp быстрее для запросов с 0 записей в
sales
(т.к. нет запроса к СУБД), для 1, 10, 100 записей, для нескольких тысяч и, возможно, десятков, сотен тысяч записей вsales
, в итоге производительность зависит от запроса, данных и т.д.Также пакет DaxSharp может использоваться без СУБД, например, с данными из файла или из API.
Хороший вопрос, да, описано больше разделение ресурсов (ноды ClickHouse) средствами Hangfire, т.е. например, на CH1 не более 2 запросов, на CH2 — не более одного, и т.д.
Наверно описано больше не балансирование, а соблюдение ограничений для ресурсов, т.е. с предложенным подходом любое балансирование (которое также нужно имплементировать) будет валидным для ресурсов. Например, для CH1 не будет условно 3 запросов одновременно.
Выбор очереди (и по сути ClickHouse) при отправке тоже нужно имплементировать, это и будет формально балансирование. Например, можно для имплементации балансирования использовать информацию о работах в очередях через
EnqueuedJobs
и выбирать очередь с наименьшим количеством работ в ней, или простейший вариант балансирования — выбор случайной ноды ClickHouse, также может быть и другая логика балансирования с учетом настроек или приоритетов нод ClickHouse и т.д., т.е. описано только соблюдение ограничений на ресурсы средствами HangfireКак вариант — следит за очередью, к кофе-машине
Наверно единого оптимального решения нет, если Hangfire уже используется и нет планов с него уходить, то можно и его более глубоко использовать.
Akka .NET интересен, но в нем нужно переходить на акторы, и он подходит для всего приложения. Выглядит так, что его удобно использовать для новых проектов, но для существующих требует время на переход.
Да, критерий Кохрена-Кокса удобен в частном случае, и может быть сложно и развернуть две версии одновременно, и встроить критерий в тесты-бенчмарки. Как вариант, критерий удобен для PR'ов. По поводу параллельного выполнения тестов-бенчмарков — да, ускоряет, но чтобы бенчмарки были актуальными (т.к. это не только тесты, а измеряется время выполнения и оно должно быть постоянным для одного и того же бенчмарка на одной и той же версии), машины должны быть «условно одинаковыми», тесты не должны влиять друг на друга и т.д. Т.е. при параллельном варианте если условно «раскидать по всем нодам», то и результаты с них могут быть трудно сопоставимыми.
Вы привели хороший и наглядный пример анализа одного конкретного запроса вручную после его выполнения. Действительно, если запрос один, и он оптимизируется вручную, есть возможность несколько раз его выполнить, посмотреть план выполнения запроса, логи и т.д. — кардинальности не нужны, но это частная задача.
В движке Visiology решается общая задача — оптимизация произвольного (не конкретного) SQL запроса до его выполнения (не после), и без дополнительных запросов к СУБД (например, для подсчета уникальных значений комбинации полей одной таблицы), и оптимизация «с первой попытки» (не после просмотра логов и выполнения, возможно, неоптимального запроса), в таком случае актуальны кардинальности.
Окей, заявка принята)
Получается, "кто ж его посадит, он же памятник")
Справедливости ради, автоматическая генерация и оптимизация SQL запросов является более общей и сложной задачей по сравнению с частными случаями оптимизаций, поэтому наверно такой диссонанс) Ручная "человеческая" оптимизация SQL действительно может давать SQL, выполняющийся быстрее автоматически сгенерированного, но ручная оптимизация SQL всегда требует затрат рабочего времени, ресурсов и т.д., по сравнению с автоматической в ДанКо
Хорошие примеры оптимизаций, выполненные вручную, — да, они реализованы в ДанКо.
В дашбордах Visiology поддерживается DAX, в чистом виде SQL не используется, поэтому все вопросы, связанные с SQL, ДанКо решает без участия пользователя.
В ДанКо поддерживается как минимум два вида кэширования: частей SQL запроса, кеширование всего результата DAX запроса. Также ДанКо поддерживает множество оптимизаций, изменяющих структуру SQL запроса, с учетом особенностей плана выполнения запроса в ClickHouse, типов данных, кардинальностей использованных столбцов и других параметров.
UPD: опять я промахнулся веткой)
Все справедливые замечания, и по логике запроса, и по плану выполнения запроса в ClickHouse. Про запрос «до оптимизации» изначально говорилось, что он синтетический и только для целей иллюстрации, ведь если сразу написать оптимальный запрос, то нечего будет оптимизировать. Плюс здесь рассматривается именно оптимизация за счет комбинаторов ClickHouse с учетом кардинальностей, но так, конечно, подразумевается, что, например, переписывание запроса вручную даст результат лучше.
UPD: Я промахнулся веткой в этом комментарии, ответил в нужной ветке
Интересная статья, появился вопрос по поводу математического аппарата, а именно, например, векторного представления текста. Векторное представление текста и все эти критерии условно синусов/косинусов угла между векторами текста и векторами текстов и поискового запроса известны и применяются уже многие десятилетия (условно более двух десятилетий).
И наверно можно согласиться, что все поисковые системы (Google, Яндекс и т.д.) провалились в сфере искусственного интеллекта (используя эти векторы для текстов) и разгромно проиграли (хотя имели миллиарды долларов и огромное исходное преимущество) "гонку AI" нейросетям и результаты поиска через нейросети намного более качественные, чем поиск через векторы текстов, который используется многие десятилетия.
В связи с этим вопрос, если результаты классификации/кластеризации и т.д. и т.п. у нейросетей на голову выше, и векторные представления текста вдоль и поперек изучены, какие перспективы у векторных представлений, нужно ли в будущем сочетать векторный подход с нейросетями для более качественных результатов?
Да, согласен, соединять план и факт из разных таблиц по полю из календаря — хорошая идея.
Тем не менее часто встречается денормализованная таблица, хоть и можно от неё отказаться с точки зрения ETL и возможностей DAX. Денормализованная таблица может остаться, например, по следующим причинам: даже в рассмотренном примере можно условно выделить три таблицы (суммарные факты за месяц, планы за месяц, детальные факты) и в каждой таблице может быть некоторое количество столбцов для аналитики (пусть условно десятки столбцов), причем значительная часть или все столбцы могут совпадать для трех таблиц. Также могут быть и условно десятки или сотни мер для каждой таблицы, причем значительная часть мер разных таблиц могут быть совпадать с точностью до имен столбцов. В таком случае создание трех таблиц вместо одной денормализованной может увеличить производительность, но и кратно увеличить количество мер (для каждой новой таблицы нужно дублировать одни и те же меры, которые были в денормализованной таблице) и в этом смысле создать некоторые сложности.
То есть нормализованная схема данных в общем случае выглядит предпочтительнее и нет рекомендаций использовать денормализованную таблицу вместо нескольких таблиц, но выбор оптимального решения по схеме данных зависит от проекта. В статье рассмотрены кейсы, как быть в том случае, если уже выбрана и используется денормализованная таблица, и какие приемы работы с ней могут быть.
Да, в общем случае я имел в виду не только эмоции разработчиков и их отношение к технологиям, но больше настроения и планы лиц, принимающих решения, с учетом затрат человеко-часов, компетенций разработчиков, стратегии развития компании и т.д.
Да, это и имплементировано, например, в Visiology и DAX Visiology работает в ClickHouse.
В этой статье PostgreSQL взята в качестве примера СУБД, можно взять любую другую.
Такое впечатление, что описанный подход полезен при любом отношении к DAX в сравнении с SQL:
если DAX "нравится", то расширяются возможности его применения;
если DAX по каким-то причинам "не нравится", то рассматривается получение SQL, соответствующего DAX.
Привет!
Здесь это больше утилита, которая может облегчить жизнь аналитику при исследовании меры на неизвестной схеме данных. Например, у аналитика нет прав доступа к схеме данных, на которой построена мера, есть только текст меры, пришел вопрос по мере и нужно найти ошибку или что-то доработать в мере.
В таком случае аналитику можно просто вставить текст меры в утилиту и уже сразу как-то сориентироваться в мере, посмотреть на использованные таблицы с тестовыми данными, на примерные результаты, на запрос DAX с
SUMMARIZECOLUMNS
, на примерный вид дашборда с мерой.Конечно, этого может быть недостаточно, тогда возможный следующий шаг — это создать схему данных из меры, при этом можно использовать сгенерированные утилитой тестовые данные и таблицы и загрузить их, например, из CSV. В этом может быть большой плюс утилиты, т.к. не нужно вручную печатать dummy данные для новой схемы. Альтернатива — переписать меру на другую схему данных (которая есть у аналитика) для более глубокого анализа, в таком случае утилита никак не может помочь (к слову, можно также перевести меру на другую схему данных также с помощью AI).
Если рассматривать DAX Visiology, то там есть и парсер, и AI чат-помощник ViTalk.
Спасибо, обновил, дополнил
В статье нет цели заменить анализ плана выполнения запроса на один показатель. И даже если нет INNER JOIN — то такой кейс не является контрпримером, т.к. ноль INNER JOIN соответствует не оптимальности запроса, а только тому, что нет информации об ухудшении производительности запроса в разрезе INNER JOIN, а по другим критериям — по плану выполения запроса, или, в частности, по подзапросам и WHERE с оконными функциями — ухудшение производительности может быть.
В качестве дополнительной метрики можно использовать количество подзапросов (считать WITH), или при помощи регулярных выражений (при возможности и необходимости) искать как раз позапросы с WHERE и оконными функциями.
В статье описывается подход применительно к тестам, не ставится задача глубокого анализа каждого SQL запроса, как может делать не только СУБД, но и, частично, например, какой-нибудь плагин Rider для разных SQL диалектов.
В контексте тестов всё фокусируется на оценке регресса, деградации, сравнении до и после, а не на детальном анализе запроса: если все SQL совпадают (определяем по совпадению двух Total хешей до и после), то деградации нет, тесты проходят и заканчиваем анализ. Делать выводы на основе нуля INNER JOIN при совпадении Total хешей всех запросов "до и после" никто не собирается.
Всё же это не выдумки, а так как всё относится к тестам, то это больше идеи на основе эспертизы разработчика, что он делает, что меняет в генерации SQL, на что это может повлиять. Так вообще можно назвать любые тесты "выдумками" и их запретить.
Если разработчик видит, что он меняет логику генерации SQL, в которой присутствуют INNER JOIN, и он может случайно увеличить их количество, и это будет считаться багом и проблемой производительности, то в таком случае есть смысл считать количество INNER JOIN, записывать в таблицу, это не более чем метаданные для простейших тестов, упрощающие работу разработчика и позволяющие сразу найти и исправить такого рода баги: был 1 INNER JOIN, стало 2 или 10 — это выглядит, как явный баг, при изменениях в логике с INNER JOIN, и нуждается в проверке и исправлении, как раз с помощью ручного анализа плана выполнения запроса.
Но в подходе из статьи анализировать вручную требуется условно не все подряд 5000 тестов в проекте, а с учетом того, что изменения в SQL тестов фиксируются, вручную необходимо проверять только несколько тестов с именениями в SQL, плюс разработчик может и без анализа плана выполнения запроса понять, что +10 INNER JOIN — это баг, и сразу перейти к исправлению, тогда анализ плана заведомо неоптимального запроса и потерю времени на это можно исключить. Причем интеграционные тесты такие баги могут не выявить, т.к. результаты запросов могут совпасть, но SQL будет разный. То же самое и с другой метрикой, например, количеством подзапросов WITH, с несколькими метриками одновременно, и т.д.