Wenn eine benutzerdefinierte Find/Browse APPLEine interaktive Anwendung in JD Edwards, die Benutzern eine grafische Oberfläche zur Datenverwaltung bietet. bei der Abfrage von F4211Die zentrale Tabelle in JD Edwards für Verkaufsauftragsdetails (Sales Order Detail). oder F0911Die Haupttabelle für Sachkonten-Transaktionen (Account Ledger) in JD Edwards. mehr als einige Sekunden benötigt, um Grid-Zeilen zurückzugeben, machen Entwickler sofort die Datenbankindizierung oder die Netzwerklatenz verantwortlich. In der überwiegenden Mehrheit der von mir durchgeführten Performance-Audits ist der Engpass jedoch hausgemacht innerhalb von JDE. Die Korrelation zwischen der Performance von JDE APPL Suchformularen und dem Business ViewEine logische Sicht auf Datenbanktabellen, die festlegt, welche Felder in einer Anwendung genutzt werden. Design ist direkt: Das Verknüpfen von Dutzenden unnötiger Spalten in einer benutzerdefinierten BSVWAbkürzung für Business View; definiert die Datenstruktur für Formulare und Berichte. zwingt die Datenbank zu kostspieligen Table ScansEin langsamer Vorgang, bei dem die Datenbank jede Zeile einer Tabelle lesen muss, um Ergebnisse zu finden. anstelle von sauberen Index SeeksEine effiziente Suchmethode, bei der die Datenbank gezielt über einen Index auf Daten zugreift..

Um einen trägen Suchbildschirm zu beheben, bitten Sie Ihren DBADatenbankadministrator; verantwortlich für die Konfiguration, Wartung und Optimierung von Datenbanksystemen. nicht einfach um einen weiteren benutzerdefinierten zusammengesetzten Index. Refaktorieren Sie stattdessen die Anwendung, um die Grid-Zeilen-zu-Business-View-Mappings an bestehenden PrimärschlüsselnEindeutige Identifikatoren für Datensätze in einer Tabelle, die einen schnellen Zugriff ermöglichen. auszurichten, und prüfen Sie das Event Grid Record is Fetched auf versteckte F4101- oder F0101-Tabellen-I/O-Schleifen. Die Beschränkung Ihrer benutzerdefinierten BSVW auf die wesentlichen Felder (in der Regel weniger als ein Dutzend), die für die Suchkriterien und die initiale Grid-Anzeige erforderlich sind, kann die SQLStructured Query Language; die Standardsprache zur Kommunikation mit relationalen Datenbanksystemen.-Ausführungszeiten bei einer Tabelle mit zig Millionen Zeilen auf unter eine Viertelsekunde senken.

Die Kosten überladener Business Views bei großen Tabellen

Schauen wir uns an, was in der Datenbank passiert, wenn ein Entwickler ein benutzerdefiniertes Find/Browse-Formular mit einer Standard-Business-View wie V4211A oder einer benutzerdefinierten View erstellt, die alle Felder aus der Tabelle F4211 (Sales Order Detail) abruft. Die JDE-Datenbank-Middleware (JDBDie Datenbank-Middleware von JD Edwards, die Anwendungsbefehle in SQL-Abfragen übersetzt.) generiert eine SELECT-Anweisung, die jede einzelne in dieser Business View definierte Spalte enthält, unabhängig davon, ob diese Felder auf dem Formular oder im Grid platziert sind. Bei der F4211, die mehr als hundert Spalten enthält, zwingt dieses nachlässige Designmuster die Datenbank dazu, hunderte Bytes nutzloser Daten pro Zeile abzurufen und zu übertragen, was den Netzwerk-Payload aufbläht und den Buffer-Pool-Speicher der Datenbank mit Daten verschwendet, die dem Benutzer niemals angezeigt werden.

Um diesen Overhead bei Suchformularen mit hohem Volumen zu vermeiden, müssen Entwickler eine schlanke, dedizierte Business View erstellen, die nur das Nötigste enthält. Das bedeutet, nur die Primärschlüssel (SDKCOO, SDDOCO, SDDCTO, SDLNID), die spezifischen Felder, die als Suchfilter im Header verwendet werden, und die Handvoll Spalten auszuwählen, die tatsächlich im Grid gerendert werden. Die Reduzierung einer Business View von mehr als hundert Spalten auf ein oder zwei Dutzend kann die SQL-Ausführungszeiten drastisch senken und den Speicherverbrauch des AnwendungsserversEin Server, der die Geschäftslogik und Anwendungen für die Clients bereitstellt. während intensiver Benutzersitzungen oft um bis zu zwei Drittel reduzieren.

Ein weiterer häufiger Performance-Killer ist das Verknüpfen von Tabellen innerhalb der Business View, um Beschreibungsfelder anzuzeigen, wie z. B. das Verknüpfen von F4211 mit F4101 über die Kurzartikelnummer (SDITM). Wenn diese Join-Keys nicht ordnungsgemäß an bestehenden Datenbankindizes ausgerichtet sind, umgeht der Datenbank-OptimizerEine Komponente des Datenbanksystems, die den effizientesten Weg zur Ausführung einer Abfrage berechnet. den Primärindex der F4211 vollständig. Anstelle eines schnellen Index Range ScansEin Suchvorgang, bei dem ein Teilbereich eines Indexes effizient durchlaufen wird. führt die Datenbank einen kostspieligen Nested LoopEine Methode zur Verknüpfung von Tabellen, bei der für jede Zeile der ersten Tabelle die zweite Tabelle durchsucht wird. oder Hash Join aus, der einen Full Table Scan auf Millionen von Verkaufsauftragszeilen auslöst und eine Suche im Subsekundenbereich in ein minutenlanges System-Freezing verwandelt.

Wie das Mapping der Suchkriterien die Index-Auswahl bestimmt

Wenn ein Benutzer auf einem Find/Browse-Formular auf "Find" klickt, übersetzt der EnterpriseOne HTML-ServerAuch JAS genannt; er verarbeitet die Web-Anfragen der Benutzer und kommuniziert mit dem Enterprise Server. die als Filterfelder gemappten Form Control (FC) Felder in eine dynamische SQL-WHERE-Klausel. Wenn Ihre benutzerdefinierte Anwendung eine Tabelle mit hohem Volumen wie die F4211 abfragt, die häufig mehrere Millionen Zeilen überschreitet, verlässt sich der Datenbank-Optimizer darauf, dass diese Filterfelder mit Indexstrukturen übereinstimmen. Das Mapping eines Filterfeldes auf eine nicht indizierte Spalte zwingt die Datenbank dazu, jede Zeile auszuwerten, was eine Millisekunden-Abfrage in eine mehrsekündige Systembelastung verwandelt.

Eingeschränkte Wildcard-Suchen mit dem Prozentzeichen in Spalten, denen eine ordnungsgemäße Indizierung fehlt, verursachen schwere Performance-Einbußen. Wenn ein Benutzer einen Teilwert in ein nicht indiziertes Beschreibungsfeld eingibt, bricht die Datenbank-Engine Index Range Scans ab und greift auf einen Full Table Scan zurück. Um dies zu verhindern, müssen Entwickler die Formulareigenschaften so konfigurieren, dass die Verwendung von Wildcards in Suchfeldern mit hohem Volumen eingeschränkt wird oder die obligatorische Eingabe in indizierten Feldern erzwungen wird.

Entwickler müssen die Suchkriterien-Controls direkt auf die führenden Spalten der Primär- oder Sekundärindizes der Tabelle abstimmen. Wenn Sie beispielsweise einen benutzerdefinierten Sekundärindex für die Tabelle F4211 haben, der mit Business Unit (MCU), Order Type (DCTO) und Line Number (LNID) definiert ist, müssen die FC-Felder des Suchformulars in genau dieser hierarchischen Reihenfolge präsentiert werden. Das Weglassen der führenden MCU-Spalte und das Filtern nur nach DCTO macht den Sekundärindex nutzlos, da der Optimizer ohne die am weitesten links stehende Schlüsselspalte keinen Index Seek durchführen kann.

Die Konfiguration des Vergleichsoperators in Form Design AidDas Entwicklungswerkzeug in JD Edwards zur Erstellung und Anpassung von interaktiven Formularen. ist ebenso kritisch. Die Auswahl eines "Like"-Vergleichsoperators anstelle von "Equal To" bei numerischen Feldern, wie der Kurzartikelnummer (ITM), verhindert, dass der Datenbank-Optimizer präzise Index Seeks ausführt. Die Datenbank ist gezwungen, das numerische Feld als Zeichenfolge zu behandeln, um das Muster auszuwerten, was die CPU-Auslastung auf dem Datenbankserver während der Spitzenzeiten um fast die Hälfte erhöhen kann.

Die Falle des Grid Rec is Fetched Events und ER-Ausführungsschleifen

Das Platzieren von Datenbankabfragen oder komplexen C-Business-FunktionenIn C geschriebene Programmeinheiten (BSFN), die komplexe Geschäftslogik in JD Edwards ausführen. innerhalb des Events Grid Record is Fetched ist der häufigste Architekturfehler, den ich in benutzerdefinierten Find/Browse-Anwendungen sehe. Entwickler nutzen dieses Event oft, um ergänzende Daten abzurufen, wie z. B. das Abrufen eines Alpha-Namens aus der Address Book Master Tabelle (F0101) für jede Zeile. Wenn eine Benutzerabfrage mehrere hundert Grid-Datensätze zurückgibt, wird eine einzelne F0101-Fetch-Business-Funktion innerhalb dieses Events hunderte Male ausgeführt. Was während der lokalen Entwicklung wie ein vernachlässigbarer Datenbankaufruf im Millisekundenbereich aussieht, eskaliert in der Produktion zu einer sich summierenden mehrsekündigen Verzögerung, wenn es mit diesen hunderten Zeilen multipliziert wird.

Um diese Ausführungsschleife zu eliminieren, müssen Sie die Last des Datenabrufs zurück auf die Datenbank-Engine oder den Speicher verlagern. Anstatt serielle JDB_Fetch- oder BSFN-Aufrufe pro Zeile auszuführen, ändern Sie die zugrunde liegende Business View so, dass die Beschreibungstabellen direkt verknüpft werden, z. B. durch Verknüpfung von F4211 mit F4101 für Artikelbeschreibungen. Wenn ein direkter Tabellen-Join aufgrund komplexer Geschäftslogik unmöglich ist, ersetzen Sie die zeilenweisen Datenbankzugriffe durch ein speicherbasiertes Cache-Muster. Die Verwendung von JDE-Cache-APIApplication Programming Interface; eine Schnittstelle zur Programmierung und zum Datenaustausch zwischen Softwarekomponenten.-Funktionen wie JDEDB_CreateCache und JDB_FindKey innerhalb Ihrer Event RulesDie Skriptsprache in JD Edwards, mit der Logik an Formular- oder Berichtsereignisse gebunden wird. ermöglicht es Ihnen, Referenzdaten einmal abzurufen und Hochgeschwindigkeits-Lookups im Speicher durchzuführen.

Für Suchformulare mit hohem Volumen, die Tausende von Zeilen verarbeiten, ist die effektivste Strategie, das Event Grid Record is Fetched vollständig zu deaktivieren. Sie können statische Stammdaten wie Zahlungsbedingungen oder Kostenstellen während des Events Post Dialog is Initialized in einen benutzerdefinierten Runtime-Cache vorladen. Indem Sie diese statischen Tabellen einmal beim Formularstart abfragen, können Sie Grid-Spalten mithilfe schneller Speicher-Lookups füllen, anstatt repetitive SQL-Anweisungen auszulösen. Die Implementierung dieser Änderung bei einem viel genutzten Arbeitsauftrags-Suchformular reduziert die Ladezeiten des Bildschirms in der Regel von mehreren Sekunden auf Bruchteile einer Sekunde.

Grid Record Fetch Loop vs Optimized DB Join

Grid-Load-Konfiguration: Page-at-a-Time vs. Load-All

Standard-JDE-Grids arbeiten im Page-at-a-Time-Modus und rufen nur 10 bis 50 Datensätze ab, um die initialen Anzeigeanforderungen zu erfüllen. Dieses Standardverhalten minimiert den Speicherbedarf auf dem HTML-Server und hält die initiale SQL-Ausführungszeit unter einer Viertelsekunde. Probleme entstehen, wenn Entwickler die Eigenschaft "Load All Grid Records" aktivieren, um clientseitige Sortierungen oder Exportanforderungen zu unterstützen, ohne das zugrunde liegende Tabellenvolumen zu berücksichtigen. In einer Produktionsumgebung, in der die F4211 zig Millionen Zeilen enthält, ist eine Load-All-Konfiguration ohne obligatorische Filter ein Stabilitätsrisiko für die Middleware.

Wenn ein Benutzer eine weit offene Suche in einem Load-All-Grid ausführt, versucht der JASJava Application Server; die Komponente, die die JD Edwards Weboberfläche bereitstellt.-Server, das gesamte Grid-Objekt im Speicher aufzubauen, bevor er die Antwort rendert. Wir sehen regelmäßig eine JAS JVM Heap-ErschöpfungZustand, in dem der für Java reservierte Arbeitsspeicher voll ist, was zu Systemabstürzen oder extremen Verzögerungen führt. bei etwa 10.000 bis 15.000 Datensätzen, abhängig von der Breite der Business View und der Anzahl der versteckten Spalten. Dieser Speicherdruck löst aggressive Garbage-Collection-Zyklen aus, was die CPU-Auslastung auf dem Webserver in die Höhe treibt und schließlich zu einem 504 Gateway Timeout oder einer Web Client Exception für den Endbenutzer führt.

Entwickler müssen dieses Risiko mindern, indem sie die Systemfunktion "Set Max Rows Spoken" innerhalb der Events Dialog is Initialized oder Find Button Clicked verwenden. Die Begrenzung der Rückgabe auf 500 oder 1.000 Datensätze bietet genügend Daten für die funktionale Nutzung und stellt gleichzeitig sicher, dass der JAS-Heap stabil bleibt. Wenn die Abfrage dieses Limit überschreitet, stoppt das System den Abruf und verhindert, dass der XML-Payload auf eine Größe anwächst, die der Browser oder der Java-Heap nicht bewältigen kann.

Die Validierungslogik im Button Clicked Event sollte explizit Suchen blockieren, bei denen kritische Indexfelder wie DCTO, KCO oder AN8 leer gelassen werden. Durch die Überprüfung des Status dieser Filterfelder und die Verwendung der Funktion "Set Control Error" zwingen Sie die Benutzer, selektive Kriterien anzugeben, die die Datenbank tatsächlich optimieren kann. Diese architektonische Schutzmaßnahme ist effektiver als jeder Query-Governor auf Datenbankebene, da sie den Ressourcenverbrauch bereits auf der Anwendungsebene stoppt und die Häufigkeit von JAS "Out of Memory"-Fehlern in Distributionsumgebungen mit hohem Volumen um bis zu 80 % bis 90 % reduziert.

Page-at-a-Time vs Load-All Performance Impact

Analyse der SQL-Ausführung über CallObject- und JAS-Logs

Ein Suchformular, das zehn Sekunden oder länger hängt, ist selten ein Fehler in der Anwendungslogik; es handelt sich fast immer um eine nicht optimierte SQL-Anweisung, die eine Tabelle mit mehreren Millionen Zeilen wie die F4211 oder F0911 trifft. Sie können diese Engpässe nicht allein mit der Form Design Aid (FDA) diagnostizieren, da die JDB-Middleware die physische Datenbankebene abstrahiert. Sie müssen das rohe SQL erfassen, indem Sie das CallObject-Logging (jdedebug.log) auf dem Fat ClientEin lokaler Entwicklungsrechner, auf dem die JD Edwards Entwicklungswerkzeuge installiert sind. oder über den Server ManagerDie webbasierte Konsole zur Verwaltung und Überwachung der JD Edwards Server-Infrastruktur. für eine spezifische Web-Sitzung aktivieren, um genau zu sehen, was die Datenbank tun soll.

Suchen Sie im jdedebug.log nach dem String "SELECT ... FROM", gefolgt von der Zeile "OCI Execute" oder "SQL Execute". Dies liefert die SQL-Ausführungszeit im jdedebug.log in Mikrosekunden und ermöglicht es Ihnen, genau zu bestimmen, welcher spezifische Fetch die Benutzeroberfläche blockiert. Gleichzeitig ermöglichen JAS-Debug-Logs die Korrelation der JDE-Benutzeraktion mit einer spezifischen Thread-ID, um sicherzustellen, dass Sie nicht einer Geister-Anweisung von einer Hintergrund-UBEUniversal Batch Engine; ein Prozess zur Ausführung von Berichten oder Massendatenverarbeitungen im Hintergrund. oder einer anderen Benutzersitzung nachjagen.

Kopieren Sie die wörtliche SQL-Anweisung aus dem Log – einschließlich der Parameter-Marker – und führen Sie einen EXPLAIN PLANEin Werkzeug zur Analyse, wie die Datenbank-Engine eine SQL-Abfrage ausführen wird, um Performance-Engpässe zu finden. in Ihrem Datenbank-Management-Studio aus. Es ist ein weit verbreiteter Irrglaube, dass JDE immer den in der Business View (BSVW) definierten Index verwendet. Wenn der Benutzer nach einer nicht indizierten Spalte in einem Grid-Header filtert, kann der Datenbank-Optimizer standardmäßig einen Full Table Scan durchführen, unabhängig davon, wie Sie das Suchverhalten während der Entwicklungsphase geplant haben.

Performance-Einbußen resultieren auch aus hochfrequenten SQL-Anweisungen mit kurzer Dauer, die auf verschachtelte Schleifen (Nested Loops) hindeuten. Wenn das Log hunderte identische SELECT-Anweisungen auf die F0101 innerhalb eines kurzen Fensters von wenigen Sekunden zeigt, haben Sie wahrscheinlich Logik im Event Grid Rec is Fetched, die einen manuellen Fetch für Stammdaten durchführt. Diese zeilenweise Verarbeitung verursacht massiven Overhead in der Kommunikation zwischen JAS und Enterprise-Server. Das Verschieben dieser Fetches in den initialen BSVW-Join oder die Verwendung einer C-BSFN mit einem Cache-Handle kann diese hunderte Datenbankzugriffe auf eine einzige Ausführung reduzieren.

Die Optimierung einer benutzerdefinierten APPL Business View umfasst mehr als nur die Auswahl von Spalten; sie erfordert ein tiefes Eintauchen in den zugrunde liegenden SQL-Ausführungsplan und die Index-Auswahl. Wenn Ihre EnterpriseOne 9.2Die aktuelle Hauptversion der JD Edwards ERP-Software.-Umgebung so abgestimmt ist, dass das Anwendungsdesign mit den Datenbank-Realitäten übereinstimmt, eliminieren Sie die Latenz, die Endbenutzer fälschlicherweise für Systeminstabilität halten.