Ha multidimenzionális adatbázist használ adatforrásként, teljesítménybeli problémákat tapasztalhat, amelyek azt eredményezhetik, hogy szuboptimális multidimenzionális adatbázis (MDX) lekérdezések jönnek létre.
A terv módosításával javíthatja az Oracle Analytics által generált MDX-lekérdezések teljesítményét. Ennek óriási hatása lehet, nemcsak a kimutatás teljesítményére, hanem az adatbázisban felhasznált erőforrások mértékére is. A támogatott és nem támogatott függvények használata nagy hatással van a létrehozott MDX-lekérdezésekre, és ezzel a teljesítményre is.
Minden használati eset egyedi, ezért a fejlesztőcsapat feladata, hogy áttekintse a lehetőségeket, elemezze az Oracle Analytics lekérdezési naplókat, és kiválassza az Ön használati esetének legjobb megoldást.
Ez a témakör nem foglalkozik az Ön infrastruktúrája (például hálózatok, böngészők vagy kimutatásbemutatók) által okozott teljesítményproblémákkal.
Metodika
Az Oracle azt javasolja, hogy hajtsa végre a következő feladatokat a teljesítmény növelése érdekében. Fontos megérteni az MDX-lekérdezés struktúráját, valamint az Oracle Analytics által létrehozott lekérdezési naplókat is.
Kijelölési lépések optimalizálása
A kiválasztási lépések optimalizálásával leegyszerűsítheti az MDX-lekérdezéseket, csökkentheti a generált MDX-lekérdezések számát, és növelheti a teljesítményt.
A következő ábrán egy példa látható, amely összehasonlítja az optimalizált és a nem optimalizált kiválasztási lépéseket.
CASE utasítások
A CASE
utasítás funkcióit az MDX-lekérdezések nem támogatják, és mindig az Oracle Analytics szolgáltatásban kell őket alkalmazni. A CASE
utasításokkal kapcsolatban ebben a szakaszban ismertetett logika a legtöbb olyan függvényre érvényes, amelyet az MDX-lekérdezések nem támogatnak (if null
stb.).
A CASE
utasítások használatának előnyei és hátrányai is vannak. Ha CASE
utasításokat ír a kimutatásképletekbe, ezek nem kerülnek be az MDX-be. Ez egyszerűsítheti az MDX-lekérdezést, és javíthatja a teljesítményt. Ennek azonban negatívuma is van, mégpedig az, hogy nem olyan hatékony a szűrés – ez azt jelenti, hogy a lekérdezés a szükségesnél több rekordot adhat vissza.
A CASE
utasítás használatára a következő korlátozások vonatkoznak:
CASE
utasítás nem kombinál össze több tagot, akkor az utasításban használt alaposzlopnak külön rejtett oszlopként kell szerepelnie a lekérdezésben és a nézetekben.CASE
utasítás több tagot kombinál össze, az alaposzlop nem szerepelhet a nézetben anélkül, hogy hatással lenne az összesítés szintjére. Ilyen esetben:
SUM
, MAX
, MIN
). Ez csak akkor működik, ha a belső összesítési szabályt a tagok kombinálására használják, és megfelelő eredményeket ad.FILTER függvény
A CASE
utasítással ellentétben a FILTER
függvény elküldhető végrehajtásra az adatbázisba.
A kimutatásképletekben a FILTER
függvény használatának fő előnye, hogy a kijelölés alkalmazásra kerül az MDX-lekérdezésben, és csökken az adatbázisból kiszámított és lekért adatok mennyisége.
A FILTER
függvény használatának fő hátránya, hogy növelheti a végrehajtott MDX-lekérdezések számát. Alapértelmezés szerint minden használt FILTER
függvényhez egyetlen lekérdezés kerül végrehajtásra.
A CASE és a FILTER összehasonlítása példával
Ebben a példában a felhasználó egy kimutatást kér, amely negyedévenként és a kiválasztott termék cikkszáma szerint mutatja a nyereséget. Ezenkívül a cikkszámok 12 kategóriába vannak csoportosítva. Az Other Cola kategóriához az LOB következő termékei vannak hozzárendelve: Cola, Diet Cola és Shared Diet Cola.
Íme a CASE
utasítás logikai lekérdezése:
SELECT 0 s_0, CASE when XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('Cola','Diet Cola','Shared Diet Cola') THEN 'Other Cola' ELSE XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" END s_1, DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_2, DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_3, DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_4, SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_5, SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_6, SORTKEY(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_7, XSA('Admin'.'Sample.BasicPM')."Product"."Category" s_8, XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" s_9, XSA('Admin'.'Sample.BasicPM')."Year"."Quarter" s_10, XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" s_11 FROM XSA('Admin'.'Sample.BasicPM') ORDER BY 8 ASC NULLS LAST, 11 ASC NULLS LAST, 5 ASC NULLS LAST, 2 ASC NULLS LAST, 7 ASC NULLS LAST, 10 ASC NULLS LAST, 4 ASC NULLS LAST, 6 ASC NULLS LAST, 9 ASC NULLS LAST, 3 ASC NULLS LAST FETCH FIRST 125001 ROWS ONLY
Nincs olyan csoportosítás, amely a CASE
utasításon alapul. Egy egyszerű MDX-lekérdezés jön létre, a CASE
utasítást az Oracle Analytics dolgozza fel:
With set [_Product3] as 'Descendants([Product], [Product].Generations(3), leaves)' set [_Year2] as 'Descendants([Year], [Year].Generations(2), leaves)' select { [Measures].[Profit] } on columns, NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties GEN_NUMBER, [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows from [Sample.Basic]
A CASE
utasítás végrehajtásra kerül a BI Serveren, és ez az alapján látható, hogy az adatbázis beállítása database 0:0,0
lesz:
RqList <<11777451>> [for database 0:0,0] D1.c6 as c6 [for database 0:0,0], D1.c4 as c4 [for database 0:0,0], case when D1.c7 in ([ 'Cola', 'Diet Cola', 'Shared Diet Cola'] ) then 'Other Cola' else D1.c7 end as c2 [for database 0:0,0], D1.c5 as c5 [for database 0:0,0], D1.c3 as c3 [for database 0:0,0], D1.c1 as c1 [for database 0:0,0], D1.c7 as c7 [for database 0:0,0], D1.c8 as c8 [for database 0:0,0]
Alternatív megoldásként használhat szűrőt a profit mérőszámaira, hogy csak a szükséges LOB-tagokat kérje le. Ebben a forgatókönyvben három mérőszámot hoz létre a megfelelő szűrőkkel.
Íme a FILTER
utasítás logikai lekérdezése:
SELECT 0 s_0, DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_1, DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_2, DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_3, SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_4, SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_5, SORTKEY(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_6, XSA('Admin'.'Sample.BasicPM')."Product"."Category" s_7, XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" s_8, XSA('Admin'.'Sample.BasicPM')."Year"."Quarter" s_9, FILTER(XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" USING XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('Cola','Diet Cola','Shared Diet Cola')) s_10, FILTER(XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" USING XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('Sasprilla','Birch Beer','Dark Cream')) s_11, FILTER(XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" USING XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('xxxxx')) s_12 FROM XSA('Admin'.'Sample.BasicPM') ORDER BY 7 ASC NULLS LAST, 10 ASC NULLS LAST, 4 ASC NULLS LAST, 6 ASC NULLS LAST, 9 ASC NULLS LAST, 3 ASC NULLS LAST, 5 ASC NULLS LAST, 8 ASC NULLS LAST, 2 ASC NULLS LAST FETCH FIRST 125001 ROWS ONLY
Ebben a forgatókönyvben három lekérdezés jön létre (minden szűrőhöz egy), és teljesítménybeli problémák lépnek fel.
1. lekérdezés:
With set [_Product3] as 'Filter([Product].Generations(3).members, ((IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "xxxxx")))' set [_Year2] as 'Descendants([Year], [Year].Generations(2), leaves)' select { [Measures].[Profit] } on columns, NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties MEMBER_NAME, GEN_NUMBER, property_expr([Product], [MEMBER_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category_Null_Alias_Replacement"), property_expr([Product], [Default], Ancestor(currentaxismember(), [Product].Generations(2)), "Category"), property_expr([Product], [MEMBER_UNIQUE_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Member Key"), property_expr([Product], [Memnor], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Memnor"), [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows from [Sample.Basic] ]]
2. lekérdezés:
With set [_Product3] as 'Filter([Product].Generations(3).members, ((IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Birch Beer") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Dark Cream") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Sasprilla")))' set [_Year2] as 'Descendants([Year], [Year].Generations(2), leaves)' select { [Measures].[Profit] } on columns, NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties MEMBER_NAME, GEN_NUMBER, property_expr([Product], [MEMBER_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category_Null_Alias_Replacement"), property_expr([Product], [Default], Ancestor(currentaxismember(), [Product].Generations(2)), "Category"), property_expr([Product], [MEMBER_UNIQUE_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Member Key"), property_expr([Product], [Memnor], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Memnor"), [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows from [Sample.Basic] ]]
3. lekérdezés:
With set [_Product3] as 'Filter([Product].Generations(3).members, ((IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Cola") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Diet Cola") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Shared Diet Cola")))' set [_Year2] as 'Descendants([Year], [Year].Generations(2), leaves)' select { [Measures].[Profit] } on columns, NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties MEMBER_NAME, GEN_NUMBER, property_expr([Product], [MEMBER_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category_Null_Alias_Replacement"), property_expr([Product], [Default], Ancestor(currentaxismember(), [Product].Generations(2)), "Category"), property_expr([Product], [MEMBER_UNIQUE_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Member Key"), property_expr([Product], [Memnor], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Memnor"), [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows from [Sample.Basic]
Alkalmazott termékszűrő példával
Jobb megközelítés, ha a termékoszlopot egyetlen mérőszámoszloppal, szűrő nélkül szerepelteti a kimutatásban. Ezután hozzon létre egy szűrőt, amely a szükséges termékeket tartalmazza. Ha a termékeket különböző kategóriákba szeretné csoportosítani, használja a CASE
utasítást. Ebben a forgatókönyvben egyetlen MDX-lekérdezés jön létre a szűrt sorokkal, és bár az Oracle Analytics alkalmazza a CASE
utasítást, az adatok csak egy részhalmazát használja, és nem az összes rekordot.
Íme egy másik forgatókönyv, ahol a CASE
utasítások teljesítménybeli problémákat okoznak.
A fejlesztő a CASE
utasítást alkalmazza a márkák átnevezéséhez, és az irányítópultprompt segítségével a felhasználók kiválaszthatják a márkát.
Mivel a CASE
utasítás nem támogatott az MDX-ben, a Brand2
szűrője nem alkalmazható az MDX-lekérdezésben. Minden márka ki van választva, és ez nincs optimalizálva.
Ebben a forgatókönyvben az Oracle azt javasolja, hogy távolítsa el a CASE
utasítást, és nevezze át a tagokat az adatbázisban, vagy hozzon létre alternatív neveket.