MDX与SQL进行分析查询的好例子


11

在进行分析查询时,有人可以向我展示MDX与常规SQL相比的优势的好例子吗?我想将MDX查询与提供相似结果的SQL查询进行比较。

维基百科说

尽管可以将其中一些转换为传统SQL,但即使对于非常简单的MDX表达式,也经常需要笨拙的SQL表达式的合成。

但是既没有引用也没有例子。我完全知道,基础数据必须以不同的方式组织,并且OLAP每次插入都需要更多的处理和存储。(我的建议是从Oracle RDBMS迁移到Apache Kylin + Hadoop

上下文:我试图说服我的公司我们应该查询OLAP数据库而不是OLTP数据库。大多数SIEM查询都大量使用“分组依据”,“排序”和“聚合”。除了提高性能外,我认为OLAP(MDX)查询比等效的OLTP SQL更简洁,更易于读取/写入。一个具体的例子可以帮助我们理解这一点,但是我不是SQL方面的专家,更不用说MDX了。


如果有帮助,这里有一个与SIEM相关的SQL查询示例,用于查询上周发生的防火墙事件:

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

Answers:


10

MDXSQL它们分别在查询multidimensional和方面完全不同,甚至常常不可比relational databases。您不能使用MDX查询现有的关系数据库。

使用多维模型并使用MDX进行查询的主要优势在于,您正在查询预先聚合的数据,并且MDX已优化为以统计方式而非关系方式进行查询。您不再查询行和表以生成平坦的结果集,而是使用元组和集合来切片和聚合多维数据集。

可以这样想:如果您使用SQL查询来获取特定项目组的总销售额,则需要编写一个查询,该查询汇总该项目组中所有项目的所有发票行。如果使用多维数据集,并且在项目组级别具有聚合,那么将在处理过程中计算结果,并为每个项目组存储聚合,从而使查询即时进行。

多维和MDX是与基于关系集的SQL完全不同的概念。

您的示例可能会变得更加简单,因为您将进行转换,例如在数据加载过程中进行日期解析,而上个月的比较可能是calculated measure。您的首尔平均值,今天可能是calculated members

如果您的多维数据集针对您的要求进行了精心设计,我相信您可以对示例的数据集进行切片和切块,而无需编写查询,但可以在数据透视表或其他分析工具中进行。

再则没有“仅在MDX中重写SQL”。它需要一定的知识才能正确地做到这一点和不同的心态。考虑维恩图而不是结果集。

为了给您提供一个使用Adventureworks数据库的示例,请想象一下需要列出自行车类别中的客户销售订单数量的要求。

如果使用SQL进行了此操作,则需要编写一个查询,该查询将对包含某行产品的销售订单的数量进行计数,该产品恰好属于自行车类别,并将其加入到customers表中,因此这将成为一个相当复杂的查询。

-- 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
但是,甚至可以将鼠标和小车进行比较。鼠标更小,还活着。自行车的金属更多,成本更高。两者的速度堪比。
Zon 2014年

6

OLAP多维数据集/数据库具有以下特征:

  • 根据用户需求获取已经聚合的信息。
  • 方便快捷
  • 能够处理不同维度的汇总数据
  • 多维数据集使用经典的聚合函数min,max,count,sum,avg,但也可以使用特定的聚合函数。

MDX与SQL:

MDX用于导航多维数据库,并定义其所有对象(维度,层次结构,级别,成员和单元格)的查询,以(简单地)获得数据透视表的表示形式。

MDX采用许多相同的SQL关键字,像SELECTFROMWHERE。不同之处在于,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查询示例: 在此处输入图片说明

度量:单价,数量,折扣,销售额,运费
维度:时间
层次结构:年>季度>月>具有成员:

  • 年份:2010、2011、2012、2013、2014

  • 季度:Q1,Q2,Q3,Q4

  • 月:一月,二月,三月……

维度:客户
层次结构:大陆>国家>州>具有成员的城市:

  • 城市:巴黎,里昂,柏林,科隆,马赛,南特…

  • 州:卢瓦尔河大西洋省,罗讷河口省,罗讷河谷,都灵…

  • 国家:奥地利,比利时,丹麦,法国,...

  • 大陆级别:欧洲,北美,南美洲,亚洲

维度:产品
层次结构:类别>子类别>具有成员的产品:

  • 类别:食物,饮料……
  • 食品类别:Baked_food…

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.