Optimalisatie van de programmaprestaties

Inleiding

Bij kleine of middelgrote QlikView-toepassingen hoeft u zich gewoonlijk geen zorgen te maken over het ontwerp van de toepassing in relatie tot de prestaties ervan. Maar als de hoeveelheid gegevens groeit, is het mogelijk dat zowel tijds- als geheugenbeperkingen aan het licht komen in een onjuist ontworpen toepassing. Het is mogelijk met enkele eenvoudige ontwerpwijzigingen de prestaties aanzienlijk te verbeteren. In de bijlage wordt verwezen naar enkele veel voorkomende valkuilen. Daar vindt u er ook oplossingen voor.

In het algemeen worden de prestaties beter als het probleem wordt verplaatst van toepassingsobjecten naar de database die door het script wordt aangedreven. Het is vaak een vestzak-broekzaksituatie. De reactietijd wordt verbeterd en de ad-hocmogelijkheden worden verkleind. De onderstaande aanbevelingen zijn niet zaligmakend. Gebruik deze wanneer ze de algemene staat van de toepassing verbeteren of wanneer ze het verschil betekenen tussen werken en niet werken.

Hieronder vindt u een lijst van voorbeelden van toegepaste methoden voor het oplossen van de hierboven genoemde problemen. Ze zijn bedoeld om de problemen te illustreren en verwijzen u naar bruikbare QlikView-functies. Het is niet mogelijk een algemene aanbeveling te geven als het gaat om de vraag welke methode de beste is, maar de volgorde van de voorbeelden is een aanwijzing.

If ( voorwaarde (tekst),....)

If-clausules waarin tekst wordt vergeleken, zijn gewoonlijk duur. Het kan een oplossing zijn om tekst toe te wijzen aan getallen, bijvoorbeeld met autonumber (zie de voorbeelden in het voorgaande gedeelte) en/of de test in het script uit te voeren.

Het testen van teksttekenreeksen is langzamer dan het testen van numerieke waarden. Kijk eens naar de uitdrukking

If (Alfa= ‘ABC’, ‘ABC’, left (Alfa, 2))

De test kan ook direct in het script worden uitgevoerd zonder verlies van flexibiliteit.

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

De uitdrukking wordt dan

If ( Flag = 1,’ABC’, left (Alfa, 2))

en de test is veel eenvoudiger.

Sum ( If (voorwaarde, ‘veldnaam’…))

Hier is de aggregatie onafhankelijk van de tabeldimensies en het resultaat wordt gedistribueerd over de dimensies van de tabel. Het probleem kan worden opgelost door de test in het script uit te voeren en de aggregatie in de tabel, of door de hele handeling in het script uit te voeren. Er zijn talloze technieken hiervoor, zoals interval match, group by, peek of if....then....else.

In dit geval betreft het twee stappen, namelijk het testen van “Condition“ en het aggregeren van het resultaat. Als we het vorige voorbeeld nemen en de aggregatie toevoegen

Sum ( If (Alfa= ‘ABC’, Num*1.25 , Num) )

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

De uitdrukking wordt dan

Sum ( If ( Flag = 1, Num* 1.25 , Num ) )

De aggregatie kan ook direct in het script worden uitgevoerd, als volgt:

table_2:

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

table_3:

Load

Alfa,

If ( Flag = 1, Num* 1.25 , Num ) as NewNum

resident table_2 ;

 

table_4:

Load

Alfa,

Sum( NewNum ) as SumNum

resident table_3

group by Alfa ;

Opmerking: De aggregatie wordt over Alfa uitgevoerd omdat dit de dimensie in de test is.

If ( voorwaarde, Sum(‘veldnaam’)..)

Deze constructie is hier alleen opgenomen om het verschil te benadrukken met de vorige situatie. Deze aggregatie is volledig contextueel en zorgt normaal gesproken niet voor prestatieproblemen.

If ( voorwaarde1, Sum(‘veldnaam’), If (voorwaarde2, Sum(‘veldnaam’)……..

De logica van geneste If...then else... is conceptueel gemakkelijk maar kan vaak moeilijk te beheren worden. Ons zijn gevallen bekend met honderden nestniveaus. Dit legt veel beslag op zowel het geheugen als de processor. De voorwaarden kunnen vaak worden vervangen door ze te transformeren. Een standaardvoorbeeld is de aggregatie quantity*price waarbij "price" variabel is. Dit kan worden omzeild met "extended interval match". Als aan twee voorwaarden, bijvoorbeeld “A EN B” moet worden voldaan, kan de test worden vervangen door een voorwaarde “C“.

Voorbeeld:

sum((GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY)

Replaces

Sum(

If((GAC12_EFCT_DT<= GIV23_REJ_DT and

GAC12_EXPIRE_DT>GIV23_REJ_DT) and

(GAC15_EFCT_DT<= GIV23_REJ_DT and GAC15_EXPIRE_DT>GIV23_REJ_DT),

GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,

Null()))

en

Sum(

If(GAC12_EFCT_DT<= GIV23_REJ_DT,

If(GAC12_EXPIRE_DT>GIV23_REJ_DT,

If(GAC15_EFCT_DT<= GIV23_REJ_DT,

If(GAC15_EXPIRE_DT>GIV23_REJ_DT,

(GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,

Null())))))

door de velden GAC12_STD_COST en GAC15_EXCHANGE_RATE te lezen als langzaam veranderende dimensies.

De uitgebreide syntaxis van intervalmatch gebruiken om problemen met langzaam veranderende dimensies op te lossen

Tekst sorteren

In QlikView wordt automatisch geëvalueerd of een veld moet worden behandeld als numeriek, tekst of algemeen. Velden die worden geëvalueerd als tekst worden gesorteerd als tekst. Dit is de traagste sorteerbewerking. Dit kan worden aangepast zodat handmatig wordt gesorteerd op laadvolgorde. Als het sorteren van keuzelijsten enzovoorts niet nodig is, kunt u dit uitschakelen.

QlikView sorteert tekenreeks van gemengde tekens en getallen in alfanumerieke volgorde. Getallen worden gesorteerd op volgorde van waarde terwijl niet-getallen worden gesorteerd in ASCII-volgorde, in tegenstelling tot bij de traditionele sorteervolgorde waarbij alleen de ASCII-volgorde wordt aangehouden. Voorbeeld:

ASCII-sorteervolgorde Alfanumerieke sorteervolgorde
A1 A1
A10 A4
A11 A5
A30 A6
A4 A10
A5 A11
A6 A30

Dynamische titels en tekstobjecten

Dynamisch berekende uitdrukkingen kunnen vrijwel overal worden ingevoerd waar ook tekst kan worden ingevoerd. De bronnen die nodig zijn voor de evaluatie van een uitdrukking zijn echter afhankelijk van de omgeving. Uitdrukkingen in grafieken en tabellen die worden gedefinieerd in het uitdrukkingsdialoogvenster, worden alleen berekend wanneer het object zichtbaar is en de gegevens worden gewijzigd. Zij worden bijvoorbeeld niet berekend wanneer het object wordt geminimaliseerd.

Als, aan de andere kant, de objecttitel wordt berekend, wordt deze berekening uitgevoerd telkens als er een verandering optreedt. Er zijn ook vele manieren om toonvoorwaarden, berekeningsvoorwaarden enzovoort te definiëren. Deze testen worden ook te allen tijde uitgevoerd.

Sommige uitdrukkingen zijn duurder dan andere en worden duurder naarmate ze vaker moeten worden geëvalueerd. Met de introductie van asynchrone berekening is het gedrag verschoven en de effecten ervan zijn mogelijk zichtbaar in uw toepassingen.

De tijdfuncties, zoals Now() en Today(), worden geëvalueerd telkens wanneer een herberekening is vereist. Vooral de functie Now() kan kostbaar zijn omdat de toepassing elke seconde opnieuw wordt berekend.

Bijvoorbeeld:

If ( ReloadTime()+3>Now(), 'Old Data', 'New Data')

Hier denkt men bijvoorbeeld aan

If ( ReloadTime()+3>Today(), 'Old Data', 'New Data')

Als eenvoudige test kunt u de uitdrukkingen in tekstobjecten plaatsen. Probeer vervolgens formaat te wijzigen van het tekstobject met Now() erin.

Macroreactieveroorzakers ("BijVerandering")

Macro's kunnen worden gestart door reacties die worden veroorzaakt door tal van gebeurtenissen in de toepassing. Let op voor waterval- of recursieve gebeurtenissen waarbij een gebeurtenis de veroorzaker is van de volgende gebeurtenis die op zijn beurt weer een gebeurtenis in gang zet.