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


11

Чи може хто-небудь показати мені хороший приклад переваг MDX перед звичайними SQL, коли робите аналітичні запити? Я хотів би порівняти запит MDX із запитом SQL, який дає подібні результати.

У Вікіпедії сказано :

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

Але немає ні цитування, ні прикладу. Мені повністю відомо, що основні дані повинні бути організовані по-різному, і для OLAP буде потрібно більше обробки та зберігання на кожну вкладку. (Моя пропозиція - перейти з RDBMS Oracle до Apache Kylin + Hadoop )

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


Якщо це допомагає, ось зразок SEM-запиту, пов'язаного з 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". Щоб зробити це правильно і іншим способом мислення, потрібно неабияк знань. Подумайте вен-діаграми замість наборів результатів.

Щоб надати вам приклад, використовуючи базу даних пригод, уявіть собі вимогу перерахувати кількість замовлень клієнтів на продаж у категорії велосипедів.

Якщо ви робили це за допомогою 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
Навіть миша та велосипед можна порівняти. Миша менша і жива. У Bycicle є більше металу і коштує дорожче. Обидва порівнянні за швидкістю.
Зона

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

update : Цей приклад краще:

Мета запиту: отримати кількість продажів та кількість одиниць (у стовпцях) усіх сімейств продуктів (у рядках), проданих у Каліфорнії протягом першого кварталу 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.