Хороший пример MDX против SQL для аналитических запросов


11

Кто-нибудь может показать мне хороший пример преимуществ MDX по сравнению с обычным SQL при выполнении аналитических запросов? Я хотел бы сравнить запрос MDX с запросом SQL, который дает аналогичные результаты.

Википедия говорит :

Хотя некоторые из них можно перевести в традиционный SQL, часто требуется синтез неуклюжих выражений SQL даже для очень простых выражений MDX.

Но нет ни цитирования, ни примера. Я полностью осознаю, что базовые данные должны быть организованы по-другому, и OLAP потребует больше обработки и хранения для каждой вставки. (Мое предложение - перейти с СУБД Oracle на Apache Kylin + Hadoop )

Контекст: я пытаюсь убедить мою компанию, что мы должны запрашивать базу данных OLAP вместо базы данных OLTP. Большинство запросов SIEM интенсивно используют группирование, сортировку и агрегирование. Помимо повышения производительности, я думаю, что запросы OLAP (MDX) были бы более краткими и более легкими для чтения / записи, чем эквивалентный OLTP SQL. Конкретный пример поможет понять, но я не эксперт по SQL, а тем более по MDX ...


Если это поможет, вот пример SQL-запроса, связанного с SIEM, для событий брандмауэра, произошедших на прошлой неделе:

SELECT   'Seoul Average' AS term, 
         Substr(To_char(idate, 'HH24:MI'), 0, 4) 
                  || '0'        AS event_time , 
         Round(Avg(tot_accept)) AS cnt 
FROM     ( 
                SELECT                     * 
                FROM   st_event_100_#yyyymm-1m# 
                WHERE  idate BETWEEN trunc(sysdate, 'iw')-7 AND trunc(sysdate, 'iw')-3 #stat_monitor_group_query#
                UNION ALL 
                SELECT * 
                FROM   st_event_100_#yyyymm# 
                WHERE  idate BETWEEN trunc(sysdate, 'iw')-7 AND trunc(sysdate, 'iw')-3 #stat_monitor_group_query# ) pm
GROUP BY substr(to_char(idate, 'HH24:MI'), 0, 4) 
                  || '0' 
UNION ALL 
SELECT   'today' AS term , 
         substr(to_char(idate, 'HH24:MI'), 0, 4) 
                  || '0'        AS event_time , 
         round(avg(tot_accept)) AS cnt 
FROM     st_event_100_#yyyymm# cm 
WHERE    idate >= trunc(sysdate) #stat_monitor_group_query# 
GROUP BY substr(to_char(idate, 'HH24:MI'), 0, 4) 
                  || '0' 
ORDER BY term DESC, 
         event_time ASC

Ответы:


10

MDXи SQLни в коем случае не являются одинаковыми, и часто даже не сопоставимы, поскольку они запрашивают multidimensionalи relational databasesсоответственно. Вы не можете запросить существующую реляционную базу данных с помощью MDX.

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

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

Многомерный и MDX - это совершенно другое понятие, чем SQL на основе реляционных множеств.

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

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

Опять же, нет "просто переписать SQL в MDX". Требуется немало знаний, чтобы сделать это правильно, и другое мышление. Думайте венн-диаграммы вместо наборов результатов.

Чтобы дать вам пример использования базы данных adventureworks, представьте себе требование перечислить количество заказов клиентов по продажам в категории велосипедов.

Если бы вы сделали это с помощью SQL, вам нужно было бы написать запрос, который подсчитывает количество заказов на продажу, содержащее строку с продуктом, относящимся к категории байков, и объединяет ее с таблицей клиентов, чтобы это стало довольно сложным запросом. ,

-- need distinct count, we're counting orders, not order lines
SELECT count(DISTINCT soh.salesorderid)
    ,pers.FirstName + ' ' + pers.LastName
FROM sales.SalesOrderDetail sod
-- we need product details to get to the category
INNER JOIN Production.Product p ON sod.ProductID = p.ProductID
-- but we need to pass via subcategories
INNER JOIN Production.ProductSubcategory psc ON p.ProductSubcategoryID = psc.ProductSubcategoryID
-- we finally get to the category
INNER JOIN Production.ProductCategory pc ON psc.ProductCategoryID = pc.ProductCategoryID
-- we also need the headers because that's where the customer is stored
INNER JOIN sales.SalesOrderHeader soh ON sod.SalesOrderID = soh.SalesOrderID
-- finally the customer, but we don't have his name here
INNER JOIN sales.Customer c ON soh.CustomerID = c.CustomerID
-- customers
INNER JOIN Person.Person pers ON c.PersonID = pers.BusinessEntityID
-- filter on bikes
WHERE pc.Name = 'bikes'
-- but the customers table doesn't contain the concatenated name
GROUP BY pers.FirstName + ' ' + pers.LastName;

В MDX (при условии, что ваш куб хорошо спроектирован для этого требования) вы можете просто написать, потому что логика и сложность переместились в другое место:

SELECT [Measures].[Internet Order Count] ON COLUMNS,
[Customer].[Customer].Members ON ROWS
FROM [Adventure Works]
WHERE [Product].[Product Categories].[Category].[Bikes]

3
Даже мышь и велосипед можно было бы сравнить, хотя. Мышь меньше и живее. Велосипед имеет больше металла и стоит дороже. Оба сопоставимы по скорости.
Зон

6

Кубы / базы данных OLAP имеют следующие характеристики:

  • Получите уже агрегированную информацию в соответствии с потребностями пользователя.
  • Простой и быстрый доступ
  • Возможность манипулировать агрегированными данными в разных измерениях
  • Куб использует классические функции агрегирования min, max, count, sum, avg, но также может использовать определенные функции агрегирования.

MDX против SQL:

MDX предназначен для навигации по многомерным базам данных и для определения запросов по всем их объектам (измерениям, иерархиям, уровням, элементам и ячейкам), чтобы получить (просто) представление сводных таблиц.

MDX использует многие идентичны в качестве ключевых слов SQL, как SELECT, FROM, WHERE. Разница в том, что SQL создает реляционные представления, а MDX - многомерные представления данных .

Разница также видна в общей структуре двух языков:

SQL-запрос: SELECT column1, column2, ..., column FROM table
MDX-запрос:SELECT axis1 ON COLUMNS, axis2 ON ROWS FROM cube

FROMуказывает источник данных:
В SQL: одна или несколько таблиц
В MDX: куб

SELECT указывает результаты, которые нужно восстановить по запросу:

В SQL:

  • Просмотр данных в двух измерениях (строки и столбцы)
  • Строки имеют одинаковую структуру, определенную столбцами

В MDX:

  • Любое количество измерений для формирования результатов запроса.
  • Термин ось используется, чтобы избежать путаницы с размерами куба.
  • Нет особого значения для строк и столбцов, но вы должны определить каждую ось: axe1 определяет горизонтальную ось, а ось 2 определяет вертикальную ось.

Пример запроса MDX: введите описание изображения здесь

Меры : Цена за единицу, Количество, Скидка, SalesAmount,
Измерение фрахта :
Иерархия времени : Год> Квартал> Месяц> с членами:

  • Год: 2010, 2011, 2012, 2013, 2014

  • Квартал: Q1, Q2, Q3, Q4

  • Месяц: январь, февраль, март…

Измерение :
Иерархия клиентов : Континент> Страна> Штат> Город с членами:

  • Город: Париж, Лион, Берлин, Кельн, Марсель, Нант ...

  • Штат: Луара Атлантическая, Буш дю Рон, Бас Рин, Турин ...

  • Страна: Австрия, Бельгия, Дания, Франция, ...

  • Континентальный уровень: Европа, Северная Америка, Южная Америка, Азия

Измерение :
Иерархия продуктов : Категория> Подкатегория> Продукт с членами:

  • Категория: Еда, Напиток…
  • Еда категории: запеченные_пищевые…
  • ...

1

обновление : этот пример лучше:

Цель запроса: получить объем продаж и количество единиц (в столбцах) всех семейств продуктов (в строках), проданных в Калифорнии в первом квартале 2010 года.

MDX

SELECT  {[Measures].[Unit Sales], [Measures].[Store Sales]} ON COLUMNS,
      {[Products].children} ON ROWS
FROM  [Sales]
WHERE ([Time].[2010].[Q1], [Customers].[USA].[CA])

SQL

SELECT SUM(unit_sales) unit_sales_sum, SUM(store_sales) store_sales_sum
FROM sales
  LEFT JOIN products ON sales.product_id = products.id
  LEFT JOIN product_classes ON products.product_class_id = product_classes.id
  LEFT JOIN time ON sales.time_id = time.id
  LEFT JOIN customers ON sales.customer_id = customers.id
WHERE time.the_year = 2010 AND time.quarter = 'Q1'
  AND customers.country = 'USA' AND customers.state_province = 'CA'
GROUP BY product_classes.product_family
ORDER BY product_classes.product_family

источник: Замечания по использованию для Modrian (который переводит запросы MDX для использования в реляционных базах данных)


Я нашел достойный пример, хотя SQL не намного сложнее (по сравнению с SaasBase вместо MDX):

введите описание изображения здесь

источник: «OLAP» в реальном времени для больших данных (+ варианты использования) - bigdata.ro 2013

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.