Seite 1 von 1

Subpage Performance Problem

Verfasst: 12. März 2021 14:20
von stony
Hallo,
ich habe in einer Subpage eine Zeile, welche für eine Artikel eine Summenzeile hat und darunter die einzelnen Zeilen.
Es gibt nun ein Boolean (Produzieren) und wenn ich dieses in der Summenzeile anklicke, möchte ich es auch bei den entsprechenden Zeile für den Artikel setzen.
Dafür habe ich folgenden Code im Trigger OnValidate
Code:
l_produzieren := Produzieren;
l_Gruppenmerkmal := Gruppenmerkmal;
l_Untergruppenmerkmal := UnterGruppenmerkmal;
l_Artikelnr := "Artikelnr.";

IF XTagTyp = XTagTyp::Artikelgruppe THEN BEGIN
  RESET;
  SETRANGE("Feinplanungsnr.","Feinplanungsnr.");
  SETRANGE(Gruppenmerkmal,l_Gruppenmerkmal);
  SETRANGE(UnterGruppenmerkmal,l_Untergruppenmerkmal);
  SETRANGE("Artikelnr.",l_Artikelnr);
  SETRANGE(XTagTyp,XTagTyp::Artikel); 
  MODIFYALL(Produzieren,l_produzieren,FALSE); 
  RESET;   
END;


Es funktioniert zwar aber es dauert ca. 10 Sekunden bis das Programm dies gemacht hat.
Wie könnte ich das lösen?

Danke und lg stony

Re: Subpage Performance Problem

Verfasst: 12. März 2021 14:25
von Timo Lässer
Gibt es in der Tabelle auch einen Key, welcher alle Felder enthält, auf die du filterst?

Je nachdem, wieviele Datensätze in der Tabelle enthalten sind, kann ein Full Table Scan ziemlich lange dauern, bis der SQL-Server alle Datensätze gefunden hat.

Re: Subpage Performance Problem

Verfasst: 12. März 2021 14:31
von stony
Habe den Key nun hinzugefügt.
Leider hat es sich nicht verbessert und aktuell sind nur ca. 20 Datensätze in der Tabelle.

Re: Subpage Performance Problem

Verfasst: 12. März 2021 16:57
von enh
SETCURRENTKEY ?

Vielleicht die Änderungen nicht in Rec sondern einer anderen Variable durchführen + CurrPage.UPDATE ?

Re: Subpage Performance Problem

Verfasst: 12. März 2021 17:59
von DanielF
Statt Modifyall durchloopen und pro Rec das modify durchführen. Meine irgendwo gelesen zu haben dass einzelnes modify schneller ist als modifyall?! Habe leider die Quelle nicht mehr - nur versuchen wenn du sehr verzweifelt bist.

Re: Subpage Performance Problem

Verfasst: 15. März 2021 07:12
von stony
Habe ich beides versucht. Leider keine Verbesserung.

Re: Subpage Performance Problem

Verfasst: 15. März 2021 10:46
von Timo Lässer
DanielF hat geschrieben:Meine irgendwo gelesen zu haben dass einzelnes modify schneller ist als modifyall?!

Das bezweifel ich aber mal ganz stark, da bei einzelnen MODIFYs jeder Datensatz (in einer Schleife) von Server geholt werden muss, um dann je Datensatz ein SQL-Statement an den SQL-Server geschickt wird.
Bei einem MODIFYALL werden keine Datensätze vom Server geholt und nur ein einziges SQL-Statement an den Server geschickt.

Bei nur wenigen Datensätzen wird man als Anwender keinen Unterschied bemerken, wenn es aber um hunderte oder mehr Datensätze geht, dann kann man schon einen Performance-Unterschied spüren.

Aber Vorsicht!
Wenn man auch den OnModify-Trigger bei allen Datensätzen ausführen möchte/muss, dann kann es (je nach Build-Version) vorkommen, dass dieser bei MODIFYALL(<Feld>,<NeuerWert>,TRUE) trotzdem nicht ausgeführt wird.
Ich habe diesbezüglich schon mehrere Build-Versionen erlebt, bei denen der Trigger nicht durchlaufen wurde.
Seit dem nutze ich MODIFYALL nur, wenn ich den Trigger nicht ausführen möchte. Möchte ich den Trigger ausführen, dann nutze ich (trotz der schlechteren Performance) MODIFY(TRUE) in einer Schleife.

Re: Subpage Performance Problem

Verfasst: 16. März 2021 10:10
von Raik Zobel
enh hat geschrieben:Vielleicht die Änderungen nicht in Rec sondern einer anderen Variable durchführen + CurrPage.UPDATE ?


Das würde ich auch eher so machen.

Probiere es so:

Aufruf im OnValidate Trigger des Produzieren Feldes:
Code:
IF UpdateLinesFromTotalLine(Rec,xRec) THEN
  CurrPage.UPDATE(FALSE);

Die Funktion:
Code:
UpdateLinesFromTotalLine(TotalLineRecord,xTotalLineRecord) : Boolean

IF TotalLineRecord.XTagTyp <> XTagTyp::Artikelgruppe THEN
  EXIT;

IF TotalLineRecord.Produzieren = xTotalLineRecord.Produzieren THEN
  EXIT;

LineRecord.SETRANGE("Feinplanungsnr.",TotalLineRecord."Feinplanungsnr.");
LineRecord.SETRANGE(Gruppenmerkmal,TotalLineRecord.Gruppenmerkmal);
LineRecord.SETRANGE(UnterGruppenmerkmal,TotalLineRecord.UnterGruppenmerkmal);
LineRecord.SETRANGE("Artikelnr.",TotalLineRecord.Artikelnr);
LineRecord.SETRANGE(XTagTyp,LineRecord.XTagTyp::Artikel);
IF NOT LineRecord.ISEMPTY THEN BEGIN
  LineRecord.MODIFYALL(Produzieren,TotalLineRecord.Produzieren,FALSE);
  EXIT(TRUE);
END;

Re: Subpage Performance Problem

Verfasst: 29. März 2021 12:42
von Kowa
Timo Lässer hat geschrieben:Wenn man auch den OnModify-Trigger bei allen Datensätzen ausführen möchte/muss, dann kann es (je nach Build-Version) vorkommen, dass dieser bei MODIFYALL(<Feld>,<NeuerWert>,TRUE) trotzdem nicht ausgeführt wird.

Auch aktuell gibt es einen bestätigten Bug bei Einsatz von MODIFYALL mit globalen Recordvariablen.
https://github.com/microsoft/AL/issues/6515

Re: Subpage Performance Problem

Verfasst: 2. Februar 2022 10:08
von Kowa
Kowa hat geschrieben:Auch aktuell gibt es einen bestätigten Bug bei Einsatz von MODIFYALL mit globalen Recordvariablen.
https://github.com/microsoft/AL/issues/6515

Die Doku ist jetzt um den Einschub bei "Important" erweitert worden (danke Natalie, für den Hinweis :wink:):
https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/methods-auto/record/record-deleteall-method#remarks
https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/methods-auto/record/record-modifyall-method#remarks
Docs hat geschrieben:By design, the global variables of the record instance being modified will be initialized to their default value during the ModifyAll/DeleteAll method execution, independently of the value that was previously set.

Re: Subpage Performance Problem

Verfasst: 2. Februar 2022 10:54
von fiddi
Hallo,

ein MODIFYALL mit Runtrigger=true ist nicht unbedingt ein Performance Gewinn, weil er im Endeffekt nichts anderes als ein Repeat- Until- Next mit Modify(true) in der Schleife ist.

Das der dann allerdings den aktuellen Record nicht benutzt, kann schon ein wenig Tricky werden. Wenn jemand z.B. den SalesHeader in einer SalesLine von extern temproär gesetzt hat, und dann ein SalesLine.ModifyAll(true) macht, der auch Daten aus dem SalesHeader im OnModify zur Aktualisierung benutzt.

Gruß Fiddi