Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 10:37
Оценка:
Есть следующая проблема. Есть одна достаточно большая таблица. Допустим Invoice. К ней соотношением 1 ко многим соединены другие таблицы, например Event и ServiceDistribution
И нужно быстро выполнять запросы вида:
SELECT
       i.SenderDivisionID,
       sd.GroupServiceTypeID,
       e.EventKindID,
       sum(sd.Amount)
FROM [Fc2].[dbo].[Invoice] i
   inner join [Fc2].[dbo].[ServiceDistributionInvoice] sd on sd.InvoiceID = i.InvoiceID
   inner join [Fc2].[dbo].[Event] e on e.InvoiceID = i.InvoiceID
GROUP BY
       i.SenderDivisionID,
       sd.GroupServiceTypeID,
       e.EventKindID

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

Теоретически запросы подобного рода можно было бы выполнять более эффективно, если не делать декартового произведения. Запрос мог бы быть что то вроде следующего:
SELECT 
     i.SenderDivisionID, 
     toArray(
         SELECT(sd.GroupServiceTypeID)
         FROM i INNER JOIN [Fc2].[dbo].[ServiceDistributionInvoice] sd on sd.InvoiceID = i.InvoiceI
     ), 
     toArray(
         SELECT (e.EventKindID) 
         FROM i INNER JOIN [Fc2].[dbo].[Event] e on e.InvoiceID = i.InvoiceID)
FROM Invoice i
GROUP BY
       i.SenderDivisionID

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

Соответственно вопрос — есть ли такие базы, которые поддерживают подобный SQL или выполняющие подобные оптимизации, позволяющие избавиться от декартового произведения большого количества огромных таблиц и объединяя их в одну? Или черт с ним с SQL — есть ли вообще решения, ориентированные на запросы подобного рода?
Re: Есть ли базы, понмающие подобный SQL:
От: Mihas  
Дата: 30.03.18 11:06
Оценка:
Здравствуйте, elmal, Вы писали:

E>Соответственно вопрос — есть ли такие базы, которые поддерживают подобный SQL или выполняющие подобные оптимизации, позволяющие избавиться от декартового произведения большого количества огромных таблиц и объединяя их в одну? Или черт с ним с SQL — есть ли вообще решения, ориентированные на запросы подобного рода?

Я подзабыл, да и не особо глубоко знаю MSSQL. Но мне кажется, правильно настроенные констрэйнты и индексы по полям, которые используются в join, должны ускорить процесс.
Поправьте, если не прав.
Re: Есть ли базы, понмающие подобный SQL:
От: torvic Голландия  
Дата: 30.03.18 11:16
Оценка: +1
Здравствуйте, elmal, Вы писали:
E>Соответственно вопрос — есть ли такие базы, которые поддерживают подобный SQL или выполняющие подобные оптимизации, позволяющие избавиться от декартового произведения большого количества огромных таблиц и объединяя их в одну? Или черт с ним с SQL — есть ли вообще решения, ориентированные на запросы подобного рода?
все обозримые базы, за исключением ранних версий mysql
поддерживают такие оптимизации
декартово произведение будет только в случае если выбран nested loop для join
Re: Есть ли базы, понмающие подобный SQL:
От: Слава  
Дата: 30.03.18 11:24
Оценка:
Здравствуйте, elmal, Вы писали:

E>Соответственно вопрос — есть ли такие базы, которые поддерживают подобный SQL или выполняющие подобные оптимизации, позволяющие избавиться от декартового произведения большого количества огромных таблиц и объединяя их в одну? Или черт с ним с SQL — есть ли вообще решения, ориентированные на запросы подобного рода?


Postgresql поддерживает toArray. В Oracle тоже наверняка должно быть подобное, у них там вообще всё есть.
Re[2]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 11:24
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Я подзабыл, да и не особо глубоко знаю MSSQL. Но мне кажется, правильно настроенные констрэйнты и индексы по полям, которые используются в join, должны ускорить процесс.

M>Поправьте, если не прав.
Так индексы по полям, которые используются в join, естественно есть, без этого вообще хрен дождешься результата. Какие индексы еще поставить чтоб работало шустро — хз. И дополнительно, нужно как то сделать так, чтоб максимально быстро выполнялись вообще все возможные запросы подобного вида, так что конкретный индекс под один запрос не получится. Чтоб не 3 таблицы, а 10 или 20. Ключевое — одна таблица основная, остальные таблицы связаны с ней 1 ко многим отношением.
Re: Есть ли базы, понмающие подобный SQL:
От: BlackEric http://black-eric.lj.ru
Дата: 30.03.18 11:30
Оценка:
Здравствуйте, elmal, Вы писали:

В MS SQL можно попробовать сделать Materialized view. Но данные займут много места
https://github.com/BlackEric001
Re[2]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 11:39
Оценка:
Здравствуйте, torvic, Вы писали:

T>все обозримые базы, за исключением ранних версий mysql

T>поддерживают такие оптимизации
T>декартово произведение будет только в случае если выбран nested loop для join
Что то непохоже. Если брать отдельные запросы подобного рода, но для двух таблиц (Invoice и Event или Invoice и ServiceDistribution), то запросы выполняются максимум за 4 секунды. А когда 3 таблицы — уже 42 секунды. 4 уже не дождаться, не говоря уже про 10. MS SQL 2017.
Re[3]: Есть ли базы, понмающие подобный SQL:
От: BlackEric http://black-eric.lj.ru
Дата: 30.03.18 11:40
Оценка:
Здравствуйте, elmal, Вы писали:

E>Здравствуйте, torvic, Вы писали:


T>>все обозримые базы, за исключением ранних версий mysql

T>>поддерживают такие оптимизации
T>>декартово произведение будет только в случае если выбран nested loop для join
E>Что то непохоже. Если брать отдельные запросы подобного рода, но для двух таблиц (Invoice и Event или Invoice и ServiceDistribution), то запросы выполняются максимум за 4 секунды. А когда 3 таблицы — уже 42 секунды. 4 уже не дождаться, не говоря уже про 10. MS SQL 2017.

А что в плане? Смотрите что ему не хватает. Возможно индексы не используются.
https://github.com/BlackEric001
Re: Есть ли базы, понмающие подобный SQL:
От: vmpire Россия  
Дата: 30.03.18 11:46
Оценка:
Здравствуйте, elmal, Вы писали:

E>Соответственно вопрос — есть ли такие базы, которые поддерживают подобный SQL или выполняющие подобные оптимизации, позволяющие избавиться от декартового произведения большого количества огромных таблиц и объединяя их в одну? Или черт с ним с SQL — есть ли вообще решения, ориентированные на запросы подобного рода?

Пол описанию это похоже на OLAP с классической схемой "звезда".
Не смотрели в сторону MS Analysis Services или длугих OLAP решений?
Re[2]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 11:46
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>В MS SQL можно попробовать сделать Materialized view. Но данные займут много места

Это точно не реально. Ибо это сработает для одного конкретного запроса, а подобных запросов требуется очень много. Там одних сырых данных без индексов на 100 гигов и это просто прототип для тестов. И при запросах нужно прошерстить именно все эти 100 гигов, точнее каждую запись каждой таблицы, но не все поля.
Re[2]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 11:50
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Пол описанию это похоже на OLAP с классической схемой "звезда".

V>Не смотрели в сторону MS Analysis Services или длугих OLAP решений?
Это почти OLAP и есть. Проблема в том, что этот MS Analysis Services не может построить даже упрощенный куб на гораздо меньшей размерности, чем требуется, просто физически. За год может и построит наверное, если купить пару вагонов винчестеров . Потому пробуем что то подобное сделать в рантайме.
Re[3]: Есть ли базы, понмающие подобный SQL:
От: BlackEric http://black-eric.lj.ru
Дата: 30.03.18 11:52
Оценка:
Здравствуйте, elmal, Вы писали:

E>Здравствуйте, BlackEric, Вы писали:


BE>>В MS SQL можно попробовать сделать Materialized view. Но данные займут много места

E>Это точно не реально. Ибо это сработает для одного конкретного запроса, а подобных запросов требуется очень много. Там одних сырых данных без индексов на 100 гигов и это просто прототип для тестов. И при запросах нужно прошерстить именно все эти 100 гигов, точнее каждую запись каждой таблицы, но не все поля.

А) Column Store + тюнинг индексов.
Б) Кластер с распараллеливанием поиска по каким либо диапазонам
Что бы порекомендовать что-то детальнее нужно детально представлять задачу.
https://github.com/BlackEric001
Re: Есть ли базы, понмающие подобный SQL:
От: sereginseregin Россия http://daremanager.sourceforge.net/ru/
Дата: 30.03.18 11:55
Оценка:
Здравствуйте, elmal, Вы писали:

Как я понимаю многие [ServiceDistributionInvoice] и многие [Event] ссылаются на один Invoice, думаю тут какая-то мешанина в запросе. Зачем нужна сумма sum(sd.Amount) и группировка по e.EventKindID ??? В подобных случаях [ServiceDistributionInvoice] и [Event] собирают и группируют в подзапросе в JOIN, что поддерживает большинство СУБД SQL. Может объясните суть запроса, чтоб его правильно перестроить?
Re[4]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 12:03
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>А) Column Store + тюнинг индексов.

BE>Б) Кластер с распараллеливанием поиска по каким либо диапазонам
BE>Что бы порекомендовать что-то детальнее нужно детально представлять задачу.
Кластер то понятно, нужна максимальная производительность на одной ноде.

Задача следующая. Есть одна большая базовая таблица порядка миллиарда записей. Она является центром звезды, то есть к ней связано множество таблиц соотношением 1 ко многим.
Нужно выполнять над такой хреновиной произвольные запросы на группировку и аггрегацию в реальном времени (ну и естественно фильтрацию, но фильтрация уменьшает объем данных, потому худшим случаем будет отсутствие фильтрации). Группировка и аггрегация может быть не только по полям центральной базовой таблицы звезды, но и по любому полю из связанных столбцов.
Классический OLAP предрассчитанный куб не построить физически. Потому нужно как то выполнять нужные запросы на группировку и агрегацию в рантайме.
Re[2]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 12:06
Оценка:
Здравствуйте, sereginseregin, Вы писали:

S>Зачем нужна сумма sum(sd.Amount) и группировка по e.EventKindID ???

Это просто пример запроса, хоторый может понадобиться. Задачу в общем случае я описал в http://rsdn.org/forum/db/7098710
Автор: elmal
Дата: 30.03.18
Re[3]: Есть ли базы, понмающие подобный SQL:
От: sereginseregin Россия http://daremanager.sourceforge.net/ru/
Дата: 30.03.18 12:19
Оценка: +1
Здравствуйте, elmal, Вы писали:

E>Здравствуйте, sereginseregin, Вы писали:


S>>Зачем нужна сумма sum(sd.Amount) и группировка по e.EventKindID ???

E>Это просто пример запроса, хоторый может понадобиться. Задачу в общем случае я описал в http://rsdn.org/forum/db/7098710
Автор: elmal
Дата: 30.03.18


Запрос явно не оптимизирован, нужен не пример запроса, а пример задачи под которую нужен запрос.

В Вашем примере вначале декартово произведение, потом группировка. Нужно наоборот — группировка, потом соединение.

В если абстрактно у вас звезда, то вначале делаете отдельные подзапросы с группировкой по каждому лучу звезды, а затем соединяете их полученные данные через JOIN.
Re[3]: Есть ли базы, понмающие подобный SQL:
От: vmpire Россия  
Дата: 30.03.18 12:44
Оценка:
Здравствуйте, elmal, Вы писали:

V>>По описанию это похоже на OLAP с классической схемой "звезда".

V>>Не смотрели в сторону MS Analysis Services или длугих OLAP решений?
E>Это почти OLAP и есть. Проблема в том, что этот MS Analysis Services не может построить даже упрощенный куб на гораздо меньшей размерности, чем требуется, просто физически. За год может и построит наверное, если купить пару вагонов винчестеров . Потому пробуем что то подобное сделать в рантайме.
Тогда может и правда попробовать columnstore, как уже предложили
Автор: BlackEric
Дата: 30.03.18
?
То же, что и с таблицами по сути, но гораздо более эффективно в случае большого количества полупустых колонок.
Re[4]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 12:55
Оценка:
Здравствуйте, sereginseregin, Вы писали:

S>В если абстрактно у вас звезда, то вначале делаете отдельные подзапросы с группировкой по каждому лучу звезды, а затем соединяете их полученные данные через JOIN.

Вот только не очень понимаю как написать подобный оптимизированный запрос.

Насколько я понимаю, имелось в виду что то вроде:
SELECT
       i.SenderDivisionID,
       sdt.GroupServiceTypeID,
       et.EventKindID,
       sum(sdt.Amount)
FROM 
    [Fc2].[dbo].[Invoice] i,
    inner join (
        SELECT sd.InvoiceID, sd.GroupServiceTypeID 
        FROM [Fc2].[dbo].[ServiceDistributionInvoice] 
        GROUP BY sd.GroupServiceTypeID
    ) sdt on sdt.InvoiceID = i.InvoiceID
   inner join (
        SELECT e.InvoiceID, e.EventKindID 
        [Fc2].[dbo].[Event] e
        GROUP BY e.EventKindID
   ) et on et.InvoiceID = i.InvoiceID
GROUP BY
       i.SenderDivisionID

Но это полная хрень и этот запрос работать не будет (он в текущем виде даже не корректен), ибо в подзапросе при группировке пропадает InvoiceId, по которому нужно джоинить.
Как сделать запрос чтоб сначала была группировка, и можно было бы результать приджоинить по invoiceId мне не очень понятно. Как и не очевидно, как это ускорит, ибо вложенные запросы с группировкой возвращают огромное количество значений, там вернутся вообще все invoiceId.
По идее оптимизатор должен понимать и делать все оптимально сам. Он на деле не так плохо и делает, там нет декартового произведения полного. Он сначала бегает по лучу звезды, объединяет с инвооисом, далее результат объединяется с другой таблицей. Но один черт это недостаточно шустро.
Re: Есть ли базы, понмающие подобный SQL:
От: Milena США  
Дата: 30.03.18 13:10
Оценка: +1
Здравствуйте, elmal, Вы писали:

E>Есть следующая проблема. Есть одна достаточно большая таблица. Допустим Invoice. К ней соотношением 1 ко многим соединены другие таблицы, например Event и ServiceDistribution



E>Соответственно вопрос — есть ли такие базы, которые поддерживают подобный SQL или выполняющие подобные оптимизации, позволяющие избавиться от декартового произведения большого количества огромных таблиц и объединяя их в одну? Или черт с ним с SQL — есть ли вообще решения, ориентированные на запросы подобного рода?


Давайте начнем с того, что чего вы используете эту схему — для транзакционной системы или для расчетов, группировок и репортинга?
Если это не транзакционная система, работающая чисто на выборку данных, то надо написать хорошее, денормализованное хранилище со star schema, без кубов. Далее при дизайне нужно партиционировать его в зависимости от того, как идёт работа с датами (чаще всего репортаж всегда месячные, квартальные или годовые), а возможно и не по дате, а ещё по чему-то. Создавайте агрегированные датамарты (агрегировать сумму, которую вы делаете в запросе, должен за вас ETL и всего один раз).
С моей точки зрения, дело совсем не в базе, а именно в дизайне, вам нужен грамотный архитектор хранилищ.
Re[4]: Есть ли базы, понмающие подобный SQL:
От: elmal  
Дата: 30.03.18 13:15
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Тогда может и правда попробовать columnstore, как уже предложили
Автор: BlackEric
Дата: 30.03.18
?

columnstore уже сделано. Ибо без этого с производительностью полный швах. На деле, что хочется:

Нужно как то сказать оптимизатору, чтобы:
1) он перестроил данные таким образом, чтобы пробегаться только по таблице Invoice. Связи 1 ко многим от таблиц звезда он как то хафигачил в столбцы массив. Это на стадии подготовки данных;
2) Далее сделать обычную группировку по таблице Invoice, но в агрегаторе делать пробег по каждому массиву, делать над ним быстрый мини groupBy и класть результат в группу, связанную с Invoice
3) Преобразовать хитрую группировку и аггрегацию на шаге 2 к требуемому выводу, это достаточно тривиально.
Собственно это я и хотел сделать явно в стартовом сообщении.

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