web-dev-qa-db-ja.com

分析クエリのMDXとSQLの良い例

分析クエリを実行するときに、通常のSQLよりもMDXが優れている例を誰かに教えてもらえますか?MDXクエリを、次のようなSQLクエリと比較したいと思います。同様の結果。

ウィキペディアは言う

これらの一部を従来のSQLに変換することは可能ですが、非常に単純なMDX式の場合でも、不格好なSQL式の合成が必要になることがよくあります。

しかし、引用も例もありません。基本となるデータは異なる方法で整理する必要があることを十分に承知しており、OLAPは挿入ごとにより多くの処理とストレージを必要とします。 (私の提案は、Oracle RDBMSから Apache Kylin + Hadoop に移行することです)

Context:OLAPデータベースではなくOLTPデータベースをクエリする必要があることを会社に納得させようとしています。ほとんどのSIEMクエリは、group-by、sort、aggregationを頻繁に使用します。パフォーマンスの向上に加えて、OLAP(MDX)クエリは、同等のOLTP SQLよりも簡潔で読み書きが容易になると思います。具体例は要点を理解するでしょうが、私はSQLの専門家ではなく、MDXははるかに少ないです...


役立つ場合は、過去1週間に発生したファイアウォールイベントのサンプル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
11
Leftium

MDXrelational databasesをそれぞれクエリしているため、SQLmultidimensionalはまったく同じではなく、比較できないこともよくあります。 MDXを使用して既存のリレーショナルデータベースをクエリすることはできません。

多次元モデルを使用し、MDXを使用してクエリを実行する主な利点は、事前に集計されたデータをクエリしていることと、MDXがリレーショナルではなく統計的な方法でクエリを実行するように最適化されていることです。行とテーブルをクエリしてフラットな結果セットを生成するのではなく、タプルとセットを使用して多次元キューブをスライスおよび集計しています。

次のように考えてください。SQLクエリを使用して特定のアイテムグループの総売上高を取得する場合、アイテムグループ内のすべてのアイテムのすべての請求書明細を合計するクエリを記述する必要があります。キューブを使用していて、アイテムグループレベルで集計を行っている場合、処理中に結果が計算され、集計がアイテムグループごとに保存されるため、クエリが瞬時に実行されます。

多次元およびMDXは、リレーショナルセットベースのSQLとはまったく異なる概念です。

データのロードプロセス中に日付の解析などの変換を行うため、先月の比較がcalculated measureになる可能性があるため、例ははるかに単純になる可能性があります。あなたのソウルの平均と今日はcalculated members

キューブが要件に合わせて適切に設計されている場合は、クエリを作成することなくサンプルのデータセットをスライスおよびダイシングできますが、ピボットテーブルまたは別の分析ツールで実行できます。

その場合も、「MDXでSQLを書き換えるだけ」ということはありません。それを正しく行うには、かなりの知識と異なる考え方が必要です。結果セットの代わりにベン図を考えてください。

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]

OLAPキューブ/データベースには次の特性があります:

  • ユーザーのニーズに応じて、すでに集約されている情報を取得します。
  • 簡単で高速なアクセス
  • さまざまなディメンションで集計データを操作する機能
  • キューブは、従来の集計関数min、max、count、sum、avgを使用しますが、特定の集計関数を使用することもできます。

MDX対SQL:

MDXは、多次元データベースをナビゲートし、そのすべてのオブジェクト(ディメンション、階層、レベル、メンバー、およびセル)に対するクエリを定義して、ピボットテーブルの表現を(単純に)取得するように作成されています。

MDXでは、SELECTFROMWHEREのように、SQLキーワードと同じものが多く使用されます。違いは、SQLではリレーショナルビューが生成されるのに対し、MDXではデータの多次元ビューが生成されることです。

2つの言語の一般的な構造にも違いがあります。

SQLクエリ:SELECT column1, column2, ..., column FROM table
MDXクエリ:SELECT axis1 ON COLUMNS, axis2 ON ROWS FROM cube

FROMはデータソースを指定します。
SQLの場合:1つ以上のテーブル
MDXの場合:立方体

SELECTは、クエリによって回復することが望まれる結果を示します。

SQLの場合:

  • 2次元のビューデータ(行と列)
  • 行は列によって定義された同じ構造を持っています

MDXの場合:

  • クエリ結果を形成する任意の数のディメンション。
  • キューブのディメンションとの混同を避けるために使用される用語の軸。
  • 行と列に特別な意味はありませんが、各軸を定義する必要があります。axe1は水平軸を定義し、軸2は垂直軸を定義します。

MDXクエリの例:enter image description here

メジャー:単価、数量、割引、売上金額、運賃
Dimension:時間
hierarchy:Year> Quarter> Month> with members:

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

  • 四半期:Q1、Q2、Q3、Q4

  • 月:1月、2月、3月、…

Dimension:顧客
hierarchy:大陸>国>州>メンバーのいる都市:

  • 都市:パリ、リヨン、ベルリン、ケルン、マルセイユ、ナント…

  • 州:ロワールアトランティック、ブーシュデュローヌ、バラン、トリノ…

  • 国:オーストリア、ベルギー、デンマーク、フランス、...

  • 大陸レベル:ヨーロッパ、北アメリカ、南アメリカ、アジア

寸法:製品
hierarchy:カテゴリ>サブカテゴリ>メンバーのある製品:

  • カテゴリ:食べ物、飲み物…
  • 食品カテゴリ:Baked_food…
6
Yassine LAADIDI

update:この例の方が優れています:

クエリの目標:2010年の第1四半期にカリフォルニアで販売されたすべての製品ファミリ(行)の販売量とユニット数(列)を取得します

[〜#〜] 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はそれほど複雑ではありません(MDXの代わりにSaasBaseと比較して):

enter image description here

ソース: ビッグデータのリアルタイム「OLAP」(+使用例)-bigdata.ro 201

1
Leftium