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.
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
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:
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:
Dans MDX:
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:
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):
source: "OLAP" en temps réel pour les Big Data (+ cas d'utilisation) - bigdata.ro 201