Analitik sorgular için iyi MDX ve SQL örneği


11

Herhangi biri bana analitik sorgular yaparken normal SQL'e göre MDX'in avantajlarına iyi bir örnek gösterebilir mi? Bir MDX sorgusu benzer sonuçlar veren bir SQL sorgusu ile karşılaştırmak istiyorum.

Wikipedia diyor ki :

Bunlardan bazılarını geleneksel SQL'e çevirmek mümkün olsa da, çok basit MDX ifadeleri için bile sıklıkla beceriksiz SQL ifadelerinin sentezini gerektirecektir.

Ancak ne bir alıntı ne de bir örnek var. Altta yatan verilerin farklı şekilde organize edilmesi gerektiğinin tamamen farkındayım ve OLAP, ek başına daha fazla işleme ve depolama gerektirecektir. (Benim önerim Oracle RDBMS'den Apache Kylin + Hadoop'a geçmek )

Bağlam: Şirketimi bir OLTP veritabanı yerine bir OLAP veritabanını sorgulamamız gerektiğine ikna etmeye çalışıyorum. Çoğu SIEM sorgusu, gruplama, sıralama ve toplama işlemlerinden yoğun şekilde yararlanır. Performans artışının yanı sıra, OLAP (MDX) sorgularının eşdeğer OLTP SQL'den daha özlü ve okunması / yazılması daha kolay olacağını düşünüyorum. Somut bir örnek noktayı eve götürür, ancak SQL'de uzman değilim, çok daha az MDX ...


Yardımcı olursa, geçen hafta gerçekleşen güvenlik duvarı olayları için SIEM ile ilgili örnek bir SQL sorgusu verilmiştir:

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

Yanıtlar:


10

MDXve SQLhiçbir şekilde aynı değildirler multidimensionalve relational databasessırasıyla sorgulandıkları ve hatta karşılaştırılamazlar . Mevcut ilişkisel veritabanınızı MDX ile sorgulayamazsınız.

Çok boyutlu bir model kullanmanın ve sorgulamak için MDX kullanmanın temel avantajı, önceden birleştirilmiş verileri sorgulamanız ve MDX'in ilişkisel bir yoldan ziyade istatistiksel bir şekilde sorgulamak için optimize edilmesidir. Artık düz bir sonuç kümesi oluşturmak için satırları ve tabloları sorgulamıyorsunuz, ancak çok boyutlu bir küpü dilimlemek ve toplamak için tuples ve kümeler kullanıyorsunuz.

Şöyle düşünün: Belirli bir öğe grubunun toplam satış tutarını elde etmek için bir SQL sorgusu kullanırsanız, öğe grubundaki tüm öğeler için tüm fatura satırlarını toplayan bir sorgu yazmanız gerekir. Bir küp kullanıyorsanız ve öğe grubu düzeyinde toplamalarınız varsa, sonuç işleme sırasında hesaplanır ve toplamalar her bir öğe grubu için saklanır ve sorguları anlık hale getirir.

Çok boyutlu ve MDX ilişkisel küme tabanlı SQL'den tamamen farklı bir kavramdır.

Örneğin, veri yükleme işleminiz sırasında tarih ayrıştırma ve geçen ay karşılaştırmanız gibi dönüşümleri yapacağınız için çok daha basit olabilir calculated measure. Seul ortalamanız ve bugüncalculated members

Küpleriniz gereksinimleriniz için iyi tasarlanmışsa, sorgu yazmanıza gerek kalmadan örneğinizin veri kümesini dilimleyebildiğinize ve doğrayabileceğinize inanıyorum, ancak bunu döndürülebilir veya başka bir analiz aracında yapın.

Sonra tekrar "sadece MDX SQL yeniden yazma" yoktur. Doğru yapmak için farklı bir bilgi ve farklı bir zihniyet gerektirir. Sonuç kümeleri yerine venn diyagramlarını düşünün.

Adventureworks veritabanını kullanarak size bir örnek sunmak için, müşteri tarafından kategori bisikletlerinde satış siparişlerinin sayısını listeleme gereksinimini düşünün.

Bunu SQL kullanarak yaptıysanız, kategori bisikletlerinden biri olan bir ürün içeren bir satır içeren müşteri siparişlerini sayan bir sorgu yazmanız ve bunu müşteriler tablosuna katılmanız gerekir, böylece bu oldukça karmaşık bir sorgu haline gelir. .

-- 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'de (küpünüz bu gereksinim için iyi tasarlanmışsa) mantık ve karmaşıklık başka bir yere taşındığı için yazabilirsiniz:

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

3
Yine de, bir fare ve bir sektör de karşılaştırılabilir. Fare daha küçük ve canlıdır. Bycicle daha fazla metale ve daha pahalıya sahiptir. Her ikisi de hız açısından karşılaştırılabilir.
Zon

6

OLAP Küpleri / veritabanları aşağıdaki özelliklere sahiptir:

  • Kullanıcının ihtiyaçlarına göre önceden toplanmış bilgiler edinin.
  • Kolay ve hızlı erişim
  • Toplam verileri farklı boyutlarda işleme yeteneği
  • Bir küp klasik toplama işlevlerini min, maks, count, sum, avg kullanır, ancak belirli toplama işlevlerini de kullanabilir.

SQL'e karşı MDX:

MDX, çok boyutlu veritabanlarında gezinmek ve tüm nesneler (boyutlar, hiyerarşiler, düzeyler, üyeler ve hücreler) üzerindeki sorguları tanımlamak için (basitçe) pivot tabloların bir temsilini elde etmek için yapılır.

MDX SQL anahtar kelime olarak birçok özdeş kullanır gibi SELECT, FROM, WHERE. Fark, SQL'in ilişkisel görünümler oluşturması , MDX ise çok boyutlu veri görünümleri üretmesidir .

Fark, iki dilin genel yapısında da görülür:

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

FROMveri kaynağını belirtir:
SQL'de: bir veya daha fazla tablo
MDX'te: bir küp

SELECT sorguyla kurtarmak istediğiniz sonuçları gösterir:

SQL'de:

  • İki boyutta veri görüntüleme (satırlar ve sütunlar)
  • Satırlar, sütunlarla tanımlanan aynı yapıya sahiptir

MDX'te:

  • Sorgu sonuçlarını oluşturmak için istediğiniz sayıda boyut.
  • Küp boyutları ile karışıklığı önlemek için kullanılan eksen terimi.
  • Satırlar ve sütunlar için özel bir anlam yoktur, ancak her ekseni tanımlamanız gerekir: axe1 yatay ekseni ve eksen 2 dikey ekseni tanımlar.

MDX sorgu örneği: resim açıklamasını buraya girin

Önlemler : Birim Fiyat, Miktar, İndirim, SatışMiktarı, Navlun
Boyutu : Zaman
hiyerarşisi : Yıl> Çeyrek> Ay> üyelerle:

  • Yıl: 2010, 2011, 2012, 2013, 2014

  • Çeyrek: Q1, Q2, Q3, Q4

  • Ay: Ocak, Şubat, Mart,…

Boyut : Müşteri
hiyerarşisi : Kıta> Ülke> Eyalet> Üyeleri olan şehir:

  • Şehir: Paris, Lyon, Berlin, Köln, Marsilya, Nantes…

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

  • Ülke: Avusturya, Belçika, Danmark, Fransa, ...

  • Kıta seviyesi: Avrupa, Kuzey Amerika, Sud Amerika, Asya

Boyut : Ürün
hiyerarşisi : Kategori> Alt kategori> üyeli ürün:

  • Kategori: Yiyecek, İçecek…
  • Gıda kategorisi: Baked_food…
  • ...

1

güncelleme : Bu örnek daha iyidir:

Sorgu hedefi: 2010'un ilk çeyreğinde Kaliforniya'da satılan tüm ürün ailelerinin (satırlar üzerinde) satış miktarını ve birim sayısını (sütunlar üzerinde) alın

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

kaynak: Modrian için kullanım notları (ilişkisel veritabanlarında kullanılmak üzere MDX sorgularını çevirir)


SQL çok daha karmaşık olmasa da (MDX yerine SaasBase ile karşılaştırıldığında) iyi bir örnek buldum:

resim açıklamasını buraya girin

kaynak: Büyük Veri için gerçek zamanlı “OLAP” (+ kullanım örnekleri) - bigdata.ro 2013

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.