web-dev-qa-db-fra.com

Bon exemple de MDX vs SQL pour les requêtes analytiques

Quelqu'un peut-il me montrer un bon exemple des avantages de MDX par rapport à SQL standard lors de requêtes analytiques? Je voudrais comparer une requête MDX avec une requête SQL qui donne des résultats similaires.

Wikipedia dit :

Bien qu'il soit possible de traduire certains d'entre eux en SQL traditionnel, cela nécessiterait fréquemment la synthèse d'expressions SQL maladroites même pour des expressions MDX très simples.

Mais il n'y a ni citation ni exemple. Je suis pleinement conscient que les données sous-jacentes doivent être organisées différemment et OLAP nécessitera plus de traitement et de stockage par insertion. (Ma proposition est de passer d'un SGBDR Oracle à Apache Kylin + Hadoop )

Contexte: J'essaie de convaincre mon entreprise que nous devrions interroger une base de données OLAP au lieu d'une OLTP. La plupart des requêtes SIEM font un usage intensif du regroupement, du tri et de l'agrégation. Outre l'augmentation des performances, je pense que les requêtes OLAP (MDX) seraient plus concises) et plus facile à lire/écrire que l'équivalent OLTP SQL. Un exemple concret nous ramènerait au but, mais je ne suis pas un expert en SQL, encore moins MDX ...


Si cela peut vous aider, voici un exemple de requête SQL liée à SIEM pour les événements de pare-feu qui se sont produits la semaine dernière:

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
11
Leftium

MDX et SQL ne sont en aucun cas les mêmes, et souvent même pas comparables, car ils interrogent multidimensional et relational databases respectivement. Vous ne pouvez pas interroger votre base de données relationnelle existante avec MDX.

Le principal avantage de l'utilisation d'un modèle multidimensionnel et de l'utilisation de MDX pour l'interroger est que vous interrogez des données pré-agrégées et que MDX est optimisé pour interroger de manière statistique plutôt que relationnelle. Vous n'interrogez plus les lignes et les tables pour produire un ensemble de résultats plat, mais vous utilisez des tuples et des ensembles pour découper et agréger un cube multidimensionnel.

Considérez-le comme ceci: si vous utilisez une requête SQL pour obtenir le montant total des ventes pour un groupe d'articles particulier, vous devrez écrire une requête qui résume toutes les lignes de facture pour tous les articles du groupe d'articles. Si vous utilisez un cube et que vous avez des agrégations au niveau du groupe d'articles, le résultat est calculé pendant le traitement et les agrégations sont stockées pour chaque groupe d'articles, ce qui rend les requêtes instantanées.

Multidimensionnel et MDX est un concept entièrement différent du SQL basé sur un ensemble relationnel.

Votre exemple pourrait devenir beaucoup plus simple, car vous effectueriez des transformations telles que l'analyse de la date pendant votre processus de chargement de données et votre comparaison du mois dernier pourrait être un calculated measure. Votre moyenne de Séoul et aujourd'hui pourrait être calculated members

Si vos cubes sont bien conçus pour vos besoins, je pense que vous pourriez découper et découper l'ensemble de données de votre exemple sans même avoir besoin d'écrire des requêtes, mais faites-le dans un outil d'analyse pivotant ou autre.

Là encore, il n'y a pas de "réécriture de SQL dans MDX". Il faut un peu de connaissances pour bien faire les choses et un état d'esprit différent. Pensez aux diagrammes de Venn au lieu des ensembles de résultats.

Pour vous donner un exemple d'utilisation de la base de données adventureworks, imaginez l'exigence de lister le nombre de commandes client par client dans la catégorie vélos.

Si vous avez fait cela en utilisant SQL, vous devez écrire une requête qui compte le nombre de commandes client contenant une ligne avec un produit qui se trouve être de la catégorie vélos et joindre cela à la table des clients, de sorte que cela deviendrait une requête assez complexe .

-- 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;

Dans MDX (à condition que votre cube soit bien conçu pour cette exigence), vous pouvez simplement écrire car la logique et la complexité ont évolué ailleurs:

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

Les cubes/bases de données OLAP ont les caractéristiques suivantes:

  • Obtenez des informations déjà agrégées en fonction des besoins de l'utilisateur.
  • Accès facile et rapide
  • Capacité à manipuler les données agrégées dans différentes dimensions
  • Un cube utilise des fonctions d'agrégation classiques min, max, count, sum, avg, mais peut également utiliser des fonctions d'agrégation spécifiques.

MDX contre SQL:

MDX est fait pour naviguer dans les bases de données multidimensionnelles et pour définir des requêtes sur tous leurs objets (dimensions, hiérarchies, niveaux, membres et cellules) pour obtenir (simplement) une représentation des tableaux croisés dynamiques.

MDX utilise de nombreux mots clés SQL identiques, comme SELECT, FROM, WHERE. La différence est que SQL produit vues relationnelles tandis que MDX produit vues multidimensionnelles des données.

La différence est également visible dans la structure générale des deux langues:

Requête SQL: SELECT column1, column2, ..., column FROM table
Requête MDX: SELECT axis1 ON COLUMNS, axis2 ON ROWS FROM cube

FROM spécifie la source de données:
En SQL: une ou plusieurs tables
Dans MDX: un cube

SELECT indique les résultats que vous souhaitez récupérer par la requête:

En SQL:

  • Une vue des données en deux dimensions (lignes et colonnes)
  • Les lignes ont la même structure définie par des colonnes

Dans MDX:

  • N'importe quel nombre de dimensions pour former les résultats de la requête.
  • Le terme axe utilisé pour éviter toute confusion avec les dimensions du cube.
  • Aucune signification particulière pour les lignes et les colonnes, mais vous devez définir chaque axe: axe1 définit l'axe horizontal et axe 2 définit l'axe vertical.

Exemple de requête MDX: enter image description here

Mesures : prix unitaire, quantité, remise, montant des ventes, fret
Dimension : Temps
hiérarchie : Année> Trimestre> Mois> avec membres:

  • Année: 2010, 2011, 2012, 2013, 2014

  • Trimestre: Q1, Q2, Q3, Q4

  • Mois: janvier, février, mars,…

Dimension : Client
hiérarchie : Continent> Pays> État> Ville avec membres:

  • Ville: Paris, Lyon, Berlin, Cologne, Marseille, Nantes…

  • Etat: Loire atlantique, Bouches du Rhône, Bas Rhin, Torino…

  • Pays: Autriche, Belgique, Danmark, France, ...

  • Niveau du continent: Europe, Amérique du Nord, Amérique du Sud, Asie

Dimension : Produit
hiérarchie : Catégorie> Sous-catégorie> produit avec membres:

  • Catégorie: Nourriture, boisson…
  • Catégorie de nourriture: Baked_food…
6
Yassine LAADIDI

mise à jour : Cet exemple est meilleur:

Objectif de la requête: Obtenez le montant des ventes et le nombre d'unités (sur les colonnes) de toutes les familles de produits (sur les lignes) vendues en Californie au premier trimestre 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

source: Notes d'utilisation pour Modrian (qui traduit les requêtes MDX pour une utilisation sur des bases de données relationnelles)


J'ai trouvé un exemple décent, bien que le SQL ne soit pas beaucoup plus complexe (par rapport à SaasBase au lieu de MDX):

enter image description here

source: "OLAP" en temps réel pour les Big Data (+ cas d'utilisation) - bigdata.ro 201

1
Leftium