分析クエリを実行するときに、通常の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
MDX
とrelational databases
をそれぞれクエリしているため、SQL
とmultidimensional
はまったく同じではなく、比較できないこともよくあります。 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キューブ/データベースには次の特性があります:
MDX対SQL:
MDXは、多次元データベースをナビゲートし、そのすべてのオブジェクト(ディメンション、階層、レベル、メンバー、およびセル)に対するクエリを定義して、ピボットテーブルの表現を(単純に)取得するように作成されています。
MDXでは、SELECT
、FROM
、WHERE
のように、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の場合:
MDXの場合:
メジャー:単価、数量、割引、売上金額、運賃
Dimension:時間
hierarchy:Year> Quarter> Month> with members:
年:2010、2011、2012、2013、2014
四半期:Q1、Q2、Q3、Q4
月:1月、2月、3月、…
Dimension:顧客
hierarchy:大陸>国>州>メンバーのいる都市:
都市:パリ、リヨン、ベルリン、ケルン、マルセイユ、ナント…
州:ロワールアトランティック、ブーシュデュローヌ、バラン、トリノ…
国:オーストリア、ベルギー、デンマーク、フランス、...
大陸レベル:ヨーロッパ、北アメリカ、南アメリカ、アジア
寸法:製品
hierarchy:カテゴリ>サブカテゴリ>メンバーのある製品:
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と比較して):