Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Automatically translated by Lango

Asynchronous includes

The easiest solution for performance improvements is to make includes “asynchronous”. As a result, the following happens:

  • Workplace loads the requested object by the user

  • Workplace shows the object to the user

  • Once the loading of the object is done, Workplace starts to load the includes

  • Once the data in an include is loaded, the data is presented. This happens for all the includes at the same time (so a small include will be shown earlier than a large include)

This is compared to the default behavior:

  • Workplace loads the requested object by the user

  • Workplace loads all includes associated with the object by the user

  • Once all the loading is done, the user is presented with all the data at once

Even though the total performance on the server will not be improved, the PERCEIVED performance by the user will be improved.

For setting includes to be asynchronous, open the page definition, scroll down the includes include and either select all and change the value for asynchronous to “yes”, or open the ones that you would like to change and set the value to “yes”.

Dropdown fields

Dropdown fields are a nice way to present users with a specific set of values. It might also be a performance killer in case the filter behind the dropdown field is not correct. A common example is when creating a client specific field which ends with CodeTypeId. If Workplace cannot find the associated CodeTypeScheme, and you set the field to be displayed as a dropdown, it will return ALL the codetypes as possible options. Another example is when making a dropdown with Contacts which depend on the current object (for example a Workorder), but presenting that field in a report where there is no Workorder in the context (as you are on a report). The dropdown would then consist of all Contacts.

When implementing a dropdown field, take the following steps:

  • Create the field with which you can select an object (this is the only case where performance issues arrive)

  • Make sure the field is set to “object selection screen”

  • Add a filter if required

  • Navigate to the object or report and fill in the field. You should be presented with the set object selection screen. Run it “as is”. If everything went well, you should be presented with the values that you expect. If not, you know you have made a mistake and you can rectify it.

  • Once you get the result that you want, change the field to “object dropdown”

When analyzing a performance problem, always check the page for dropdowns. Check how many values are in there. In case of client specific fields, double check the filters and optional scripts that retrieve the values to see if there are suboptimal queries in those.

Large reports/includes

This one should be quite obvious, but reports with a lot of result with negatively impact the performance. Especially if these are added as an include to an object. If, for whatever reason, an asynchronous include is not possible, consider changing the filtering on these reports to give back a more limited set of data. This is mostly a functional decision:

  • Make sure large reports are run manually, so the user is aware of the report taking a long time

  • See if you can scale down the amount of data on an include, as an include should only present the user with data that is relevant for that object at that time

  • If you have dashboards for users, limit the amount of data on those (as well as make then asynchronous)

Scripting in reports

...

Asynchron umfasst

Die einfachste Lösung zur Leistungsverbesserung besteht darin, Includes "asynchron" zu machen. Als Ergebnis geschieht Folgendes:

  • Workplace lädt das vom Benutzer angefragte Objekt

  • Workplace zeigt dem Benutzer das Objekt

  • Sobald das Laden des Objekts abgeschlossen ist, beginnt Workplace damit, die Includes zu laden

  • Sobald die Daten in einem Include geladen sind, werden die Daten angezeigt. Dies geschieht für alle Includes gleichzeitig (ein kleines Include wird also früher angezeigt als ein großes Include)

Dies wird mit dem Standardverhalten verglichen:

  • Workplace lädt das vom Benutzer angefragte Objekt

  • Workplace lädt alle vom Benutzer mit dem Objekt verbundenen Includes

  • Sobald der Ladevorgang abgeschlossen ist, werden dem Benutzer alle Daten auf einmal angezeigt

Auch wenn die Gesamtleistung des Servers nicht verbessert wird, wird die vom Benutzer wahrgenommene Leistung verbessert.

Um Includes als asynchron einzustellen, öffnen Sie die Seitendefinition, blättern Sie in der Include-Liste nach unten und wählen Sie entweder alle aus und ändern Sie den Wert für asynchron auf "ja", oder öffnen Sie die Includes, die Sie ändern möchten, und setzen Sie den Wert auf "ja".

Dropdown-Felder

Dropdown-Felder sind eine gute Möglichkeit, Nutzern eine bestimmte Auswahl an Werten zu präsentieren. Es kann aber auch ein Leistungskiller sein, wenn der Filter hinter dem Dropdown-Feld nicht korrekt ist. Ein häufiges Beispiel ist die Erstellung eines kundenspezifischen Feldes, das mit CodeTypeId endet. Wenn Workplace das zugehörige CodeTypeScheme nicht finden kann und Sie das Feld so einstellen, dass es als Dropdown-Feld angezeigt wird, gibt es ALLE Codetypen als mögliche Optionen zurück. Ein weiteres Beispiel ist die Erstellung eines Dropdowns mit Kontakten, die vom aktuellen Objekt (z.B. einem Arbeitsauftrag) abhängen, aber dieses Feld in einem Bericht angezeigt wird, in dem es keinen Arbeitsauftrag im Kontext gibt (da Sie sich in einem Bericht befinden). Die Auswahlliste würde dann aus allen Kontakten bestehen.

Gehen Sie bei der Implementierung eines Dropdown-Feldes wie folgt vor:

  • Erstellen Sie das Feld, mit dem Sie ein Objekt auswählen können (dies ist der einzige Fall, in dem Leistungsprobleme auftreten)

  • Stellen Sie sicher, dass das Feld auf "Objektauswahlbild" eingestellt ist.

  • Bei Bedarf einen Filter hinzufügen

  • Navigieren Sie zu dem Objekt oder Bericht und füllen Sie das Feld aus. Sie sollten das Selektionsbild für die Objektauswahl erhalten. Führen Sie es "so wie es ist" aus. Wenn alles gut gelaufen ist, sollten Sie die erwarteten Werte erhalten. Ist dies nicht der Fall, wissen Sie, dass Sie einen Fehler gemacht haben und können ihn korrigieren.

  • Sobald Sie das gewünschte Ergebnis erhalten, ändern Sie das Feld in "Objekt Dropdown".

Wenn Sie ein Leistungsproblem analysieren, sollten Sie die Seite immer auf Dropdowns überprüfen. Prüfen Sie, wie viele Werte dort enthalten sind. Bei kundenspezifischen Feldern überprüfen Sie die Filter und optionalen Skripte, die die Werte abrufen, um zu sehen, ob es in diesen suboptimale Abfragen gibt.

Große Berichte/einschließlich

Dies sollte ziemlich offensichtlich sein, aber Berichte mit vielen Ergebnissen wirken sich negativ auf die Leistung aus. Vor allem, wenn diese als Include zu einem Objekt hinzugefügt werden. Wenn, aus welchen Gründen auch immer, ein asynchrones Include nicht möglich ist, sollten Sie überlegen, ob Sie die Filterung dieser Berichte so ändern, dass nur eine begrenzte Menge an Daten zurückgegeben wird. Dies ist hauptsächlich eine funktionale Entscheidung:

  • Stellen Sie sicher, dass große Berichte manuell ausgeführt werden, damit der Benutzer weiß, dass der Bericht viel Zeit in Anspruch nimmt.

  • Prüfen Sie, ob Sie die Datenmenge in einem Include reduzieren können, da ein Include dem Benutzer nur die Daten anzeigen sollte, die für dieses Objekt zu diesem Zeitpunkt relevant sind.

  • Wenn Sie Dashboards für Benutzer haben, begrenzen Sie die Datenmenge auf diesen (und machen Sie diese asynchron)

Skripting in Berichten

In Berichten kann Scripting verwendet werden, um bei Bedarf komplexere Formeln auszuführen. Eine Formel könnte wie folgt aussehen:

Code Block
execute("MakeComplexCalculation",WorkorderReference)

There is one downside to this: when passing values to the script (in the above case, “WorkorderReference”), these are passed as strings, NOT as objects. So that results in the scripting having to perform a second query based on the value. To sketch a hypothetical case:

  • A report returns 100 workorders

  • Based on those workorders, you pass the workorder reference to the formula script

  • You than do a query on the workorder reference, from which you get the values from the workorder and return a calculated value

The above situation results in 101 queries: one for the report, 100 for each consecutive line for which you make the calculation. A more performant option is to add all the necessary values that you need in the script in the report, hide them from the end result, but pass them to the formula. The formula call would be the followingDies hat einen Nachteil: Bei der Übergabe von Werten an das Skript (im obigen Fall "WorkorderReference") werden diese als Strings und NICHT als Objekte übergeben. Das führt dazu, dass das Skript eine zweite Abfrage auf der Grundlage des Wertes durchführen muss. Um einen hypothetischen Fall zu skizzieren:

  • Ein Bericht liefert 100 Arbeitsaufträge

  • Basierend auf diesen Arbeitsaufträgen übergeben Sie den Arbeitsauftragsverweis an das Formelskript

  • Sie führen dann eine Abfrage auf den Arbeitsauftragsbezug durch, aus der Sie die Werte aus dem Arbeitsauftrag abrufen und einen berechneten Wert zurückgeben

Die obige Situation führt zu 101 Abfragen: eine für den Bericht, 100 für jede aufeinanderfolgende Zeile, für die Sie die Berechnung durchführen. Eine leistungsfähigere Option besteht darin, alle erforderlichen Werte, die Sie im Skript benötigen, in den Bericht einzufügen, sie aus dem Endergebnis auszublenden, sie aber an die Formel zu übergeben. Der Aufruf der Formel würde folgendermaßen aussehen:

Code Block
execute("MakeComplexCalculation",WorkorderPlannedAmount,WorkorderInvoicedAmount,WorkorderSupplierMultiplier)

In the script, you would then use the (string!) values to make the necessary calculations. This will result in 1 query for the complete report.

Client specific fields

Every time you create a client specific field, this results in an additional database call for every object made which has that field on it. At certain points, this becomes a performance killer (experience learns this is about 80 client specific fields where this becomes quite slow). So take the following aspects into consideration when creating client specific fields (or when debugging performance):

...

Make client specific fields on the lowest category possible. That will result in the fields only being created for a specific subset of objects

...

Only put a client specific field on a higher category level if more than 3 sub categories need it OR the subcategories in combination with the parent category are a limited subset

...

Look at the existing fields and see if you can re-use a field or not

...

Cleanup fields that are no longer used

...

Im Skript würden Sie dann die (Zeichenfolge!) Werte verwenden, um die erforderlichen Berechnungen durchzuführen. Das Ergebnis ist eine Abfrage für den gesamten Bericht.

Kundenspezifische Felder

Jedes Mal, wenn Sie ein kundenspezifisches Feld erstellen, führt dies zu einem zusätzlichen Datenbankaufruf für jedes Objekt, das dieses Feld enthält. Ab einem bestimmten Punkt wird dies zu einem Leistungskiller (die Erfahrung zeigt, dass dies bei etwa 80 kundenspezifischen Feldern recht langsam wird). Berücksichtigen Sie also die folgenden Aspekte bei der Erstellung von kundenspezifischen Feldern (oder beim Debuggen der Leistung):

  • Legen Sie kundenspezifische Felder in der niedrigstmöglichen Kategorie an. Dies wird dazu führen, dass die Felder nur für eine bestimmte Untergruppe von Objekten erstellt werden

  • Setzen Sie ein kundenspezifisches Feld nur dann auf eine höhere Kategorieebene, wenn mehr als 3 Unterkategorien es benötigen ODER die Unterkategorien in Kombination mit der übergeordneten Kategorie eine begrenzte Teilmenge darstellen.

  • Sehen Sie sich die vorhandenen Felder an und prüfen Sie, ob Sie ein Feld wiederverwenden können oder nicht

  • Nicht mehr verwendete Felder bereinigen

  • Wenn viele verschiedene Felder erforderlich sind, sollten Sie ein unabhängiges Objekt (z. B. CodeType) mit einer bestimmten Kategorie verwenden, in das die Felder eingefügt werden. Dadurch werden unnötige Felder in einem bestimmten Objekt vermieden. Außerdem kann dies dazu führen, dass das unabhängige Objekt zu einem späteren Zeitpunkt erstellt werden kann, was die Auswirkungen auf die Leistung bei der anfänglichen Erstellung des Objekts verringert.