Wir haben eine Webanwendung, die in einer Produktionsumgebung ausgeführt wird und irgendwann klagte der Client darüber, wie langsam die Anwendung wurde.Wie vermeidet man diese sehr schwere Abfrage, die die Anwendung verlangsamt?
Wenn wir überprüft, was mit der Anwendung vorging und die Datenbank, die wir dieses „wertvolle“ Abfrage entdecken, die von mehreren Benutzern gleichzeitig ausgeführt wurde (also eine extrem hohe Last auf dem Datenbankserver zuzufügen):
SELECT NULL AS table_cat,
o.owner AS table_schem,
o.object_name AS table_name,
o.object_type AS table_type,
NULL AS remarks
FROM all_objects o
WHERE o.owner LIKE :1 ESCAPE :"SYS_B_0" AND
o.object_name LIKE :2 ESCAPE :"SYS_B_1" AND
o.object_type IN(:"SYS_B_2", :"SYS_B_3")
ORDER BY table_type, table_schem, table_name
Unsere Anwendung führt diese Abfrage nicht aus, ich glaube, es ist eine interne Hibernate-Abfrage. Ich habe wenig Informationen darüber gefunden, warum Hibernate diese extrem schwere Abfrage durchführt, also jede Hilfe, wie man sie vermeidet, wird sehr geschätzt!
Informationen zur Produktionsumgebung: Red Hat Enterprise Linux 5.3 (Tikanga), JDK 1.5, Webcontainer OC4J (mit Oracle Application Server), Oracle Database 10.1.0.4, JDBC-Treiber für JDK 1.2 und 1.3, Hibernate Version 3.2.6 .ga, Verbindungspool-Bibliothek C3P0 Version 0.9.1.
UPDATE: Dank @BalusC für claryfing, dass in der Tat es Hibernate ist, dass die Abfrage ausgeführt wird, jetzt habe ich eine bessere Vorstellung davon, was vor sich geht. Ich werde erklären, wie wir die Hibernate-Sitzung behandeln (es ist sehr rudimentär ja, wenn Sie Vorschläge haben, wie man besser damit umgehen kann!)
Wir haben einen Filter (implementiert javax.servlet.Filter) Wenn es gestartet wird (init-Methode), baut es die Sitzungs-Factory auf (dies geschieht nur einmal). Dann geht jeder HttpRequest, der an die Anwendung geht, durch den Filter und erhält eine neue Sitzung und startet eine Transaktion. Wenn der Prozess vorbei ist, kommt es durch den Filter zurück, macht das Commit der Transaktion, tötet die Hibernate-Sitzung, dann weiter auf der Forward-Seite (wir speichern die Hibernate-Sitzung in der HTTP-Sitzung nicht, weil es nie funktioniert hat gut in unseren Tests).
Jetzt kommt hier der Teil, wo ich denke, das Problem ist. In unserer Entwicklungsumgebung stellen wir unsere Apps in Tomcat 5.5 bereit, und wenn wir den Dienst starten, starten alle Filter sofort und nur einmal. In der Produktionsumgebung mit OC4J scheint das nicht so zu funktionieren. Wir stellen die Anwendung bereit und nur wenn die erste Anfrage eintrifft, instanziiert OC4J die Filter.
Dies führt mich zu glauben, dass OC4J der Filter auf jeden Anfrage (oder zumindest mehrmals, die immer noch falsch ist), eine Sitzung ab Werk auf jede Anfrage so instanziiert zu schaffen, wich führt, dass% &% #% $ # Abfrage, die zu meinem Problem führt!
Nun, ist das korrekt? Gibt es eine Möglichkeit für mich, das OC4J so zu konfigurieren, dass Filter nur einmal instanziiert werden?
Vielen Dank an euch alle, dass ihr euch die Zeit genommen habt, darauf zu antworten!
Haben Sie daran gedacht, die App so zu modifizieren, dass das Ergebnis dieser Abfrage zwischengespeichert wird? Das Ergebnis davon scheinen statische Daten zu sein, es sei denn, Sie erstellen ein DB-Verwaltungstool. –
Verwenden Sie auch den richtigen Hibernate-Dialekt und die richtigen JDBC-Oracle-Treiber? – aperkins
Ich bin sicher, wir verwenden den richtigen Dialekt, nicht so sehr auf den Treiber (aber es gab nie Probleme vorher). Und die Abfrage ist nicht Teil der Anwendung, es muss eine Ruhezustand, c3p0 oder Treiberabfrage sein, wir sind nicht sicher, wer es ausführt. Mein erster Gedanke ist der Treiber, ja, wir installieren das Neueste. –