הצטרפו לקבוצות שלנו לקבלת עדכונים מרוכזים פעם בשבוע:

ווטסאפ:
http://wa.dwh.co.il
טלגרם:
http://telegram.dwh.co.il

כיצד כשבונים עולם Business Objects ניתן להתאים את סוג האגריגציה לכל שאילתא.

 

ניקח את הדוגמא הבאה:

לפנינו טבלת Fact המכילה כ5מליון רשומות: Fact_tickets

לטבלה זאת, מפתח לוגי)  ticket_id( , קוד מחלקה (Department_id) המכיל 11 ערכים שונים וכן קוד עיר המכיל 45 ערכים שונים. את department_id  ואת city_id מפענחים dim_departments וdim_cities בהתאמה. בנוסף, ישנה טבלה dim_tickets המתארת את הפרטים הכללים של הרשומה.

כמו כן, הMeasure בטבלה הוא length_in_seconds.

ערכים לדוגמא בטבלה:

alt

נבנה עולם המכיל את הטבלה ואת טבלאות הפענוח:

alt

הבעיה: כיצד נגדיר את הMeasure בשם Length_in_seconds. אם נגדיר את האובייקט כsum(Fact_Tickets.length_in_seconds) , הוא יעבוד בצורה טובה כאשר נריץ שאילתות עם departments או cities (יבצע Group By ברמה של cities  או Departments), אך יעבוד בצורה גרועה אם נשתמש במפתח של הטבלה ( Ticket_Id) בשאילתא (אין משמעות לוגית לGroup by על מפתח של טבלה שכן הרשומות הם יחודיות גם כך).

באותה מידה , אם נגדיר את האובייקט ללא sum, כלומר Fact_Tickets.length_in_seconds, הוא יעבוד בצורה טובה כאשר נשתמש במפתח ticket_id, אך יעבוד בצורה גרועה כאשר נשתמש בcity_id או בcountry_id, שכן יגרום להצפת רשומות והסיכום בתוך הBO.

 

הפתרון:

לצורך העניין, נצטרך ליצור טבלת Fact נוספת (כמובן שנשתמש בalias) לרשומות הלא סיכומיות ונסיט את השאילתא  אליה כאשר השאילתא תרד לרמה פרטנית (עם האובייקט Ticket_id).

לAlias של טבלת ה Fact נקרא Fact_Tickets_None_agg. נחבר אותו למימדים המשותפים.

alt

כמובן שישנו Loop, לכן נגדיר Contexts לכל אחד מהFacts.

כעת נצטרך להסיט את השאילתא לפי הלוגיקה הבאה:

אם נשתמש באובייקט הפרטני (ticket_id ) השתמש בטבלת Fact_Tickets_None_agg  אחרת השתמש בטבלת Fact_Tickets. (שימו לב: שתי הטבלאות הם זהות לחלוטין)

לצורך ההסטה, נשתמש במנגנון הAggregate Aware.

נגדיר את ticket_id  כ incompatible ביחס לטבלת Fact_Tickets.

alt

כעת מגיע השוס הגדול: כיצד נגדיר את האובייקט.

יש לנו אינטרס שקודם כל הBO ייגש לטבלה המסוכמת (Fact_Tickets) יחד עם sum ורק לאחר מכן  ייגש לטבלה הפרטנית Fact_Tickets_None_agg ללא sum.

לכן נגדיר את האובייקט באופן הבא:

@Aggregate_Aware(@Aggregate_Aware(sum(Fact_Tickets.length_in_seconds),Fact_Tickets_None_agg.length_in_seconds) (

 

בואו נבדוק את האובייקט:

אם נשתמש באובייקט לבד

alt

 נקבל את הSQL הבא:

SELECT

  sum(Table__3.length_in_seconds)

FROM

  "Rosen Valves".dbo.Fact_Tickets  Table__3

 

תקין: הSum התבצע בשרת.

 

אם נוסיף לשאילתא cities או department

alt

נקבל את הSQL  הבא:

SELECT

  sum(Table__3.length_in_seconds),

  Table__2.department_name,

  Table__4.city_name

FROM

  "Rosen Valves".dbo.Dim_Departments  Table__2 INNER JOIN "Rosen Valves".dbo.Fact_Tickets  Table__3 ON (Table__2.department_id=Table__3.depatment_id)

   INNER JOIN "Rosen Valves".dbo.Dim_Cities  Table__4 ON (Table__3.city_id=Table__4.city_id)

 

GROUP BY

  Table__2.department_name,

  Table__4.city_name

תקין: עדיין הסיכום התבצע בשרת וחסכנו את פעולת הסיכום היקרה והבזבזנית בתוך הBO.

כעת נבדוק את הדבר החשוב מכל: מה קורה כאשר נרד לרמה פרטנית , כלומר נוסיף את האובייקט Ticket_id לשאילתא.

alt

הSQL שנקבל יהיה:

 

SELECT

  Fact_Tickets_None_agg.length_in_seconds,

  Table__2.department_name,

  Table__4.city_name,

  Table__6.ticket_id

FROM

  "Rosen Valves".dbo.Dim_Departments  Table__2 INNER JOIN "Rosen Valves".dbo.Fact_Tickets  Fact_Tickets_None_agg ON (Table__2.department_id=Fact_Tickets_None_agg.depatment_id)

   INNER JOIN "Rosen Valves".dbo.Dim_Cities  Table__4 ON (Fact_Tickets_None_agg.city_id=Table__4.city_id)

   INNER JOIN "Rosen Valves".dbo.Dim_Tickets  Table__6 ON (Fact_Tickets_None_agg.ticket_id=Table__6.ticket_id(

 

תקין: לא התבצע סיכום\ Group BY בשרת אלא רק הרשומות נשלפו AS IS וחסכנו את פעולת הGroup By היקרה והמיותרת.

ובא לציון גואל