Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino
Abfrage auf Oracle-DB dauert sehr labge
DAU-in:
Ich habe mich an einem Java-Agenten versucht, der Abfragen auf eine Oracle -DB startet.
Jetzt habe ich mehrere Fragen:
a) habe ich alles recyceld, was ich recyclen muss?
b) die einzelnen Abfragen dauern zwischen 7 und 8 Sekunden, kann ich die Abfrage in checkyyyenInfo anders fassen, so dass das schneller geht?
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.*;
import java.lang.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Vector;
import lotus.domino.*;
public class yyyenstellenPruefung extends AgentBase {
Session session = null;
Database dbCurrent = null; //aktuelle DB
//für Oracle-Verbindung
View oracleConfigView = null;
Document docOracleConfig = null; //Konfigurationseinstellungen für Oracle
String strOracleServer = null; //
String strOracleView = null; //
String strOracleUser = null; //
String strOraclePwd = null; //
Connection conn=null; //
ResultSet rs=null; //
Statement stmt=null; //
// zu bearbeitende Dokumente
View terminalView = null; //zur 'Ermittlung der Dokumente
long newDocs = 0;
Document terminalDoc = null; //aktuelles Terminaldoc
Document nextDoc = null;
// Protokolldokument
Document logDoc = null; //Protokoll
GregorianCalendar cal=null; //
Item logItem=null; //
int logCount=0; //
int logDocCount=1; //
public void NotesMain() {
try {
System.out.println("Agent: Check für yyyenstellenaenderungen gestartet");
session = getSession();
AgentContext agentContext = session.getAgentContext();
dbCurrent = agentContext.getCurrentDatabase(); // aktuelle Datenbank holen
//Erstellung Protokolldokument
cal = new GregorianCalendar();
logDoc = dbCurrent.createDocument();
logDoc.replaceItemValue("Form","Log");
logDoc.replaceItemValue("Lauf","Lauf vom: " + cal.get(Calendar.DATE)+"."+(cal.get(Calendar.MONTH)+1)+"."+cal.get(Calendar.YEAR)+" " + cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" Uhr");
logDoc.replaceItemValue("Start",cal.get(Calendar.DATE)+"."+(cal.get(Calendar.MONTH)+1)+"."+cal.get(Calendar.YEAR)+" " + cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" Uhr");
logDoc.replaceItemValue("Log","");
logItem = logDoc.getFirstItem("Log");
logEvent("Agent: Check für yyyenstellenüberprüfung gestartet");
logDoc.save(true,false); //einmal abspeichern, damit Abbruch ersichtlich wird
//Einlesen der Oraclekonfigurationseinstellung
oracleConfigView = dbCurrent.getView("(luConfig)");
docOracleConfig = oracleConfigView.getDocumentByKey("OracleConfig");
strOracleServer = docOracleConfig.getItemValueString("OracleServer");
strOracleView = docOracleConfig.getItemValueString("OracleView");
strOracleUser = docOracleConfig.getItemValueString("OracleUser");
strOraclePwd = docOracleConfig.getItemValueString("OraclePwd");
//Erstellen der Verbindung
// achtung: wenn hier Fehlermeldung kommt wegen fehlendem Oracle-treiber --->
//im Agent müssen die Klassen als JArdatei eingehängt sein, wird unter 'Projekt bearbeiten' angezeigt, notfalls auf OracleHomeopage suchen
logEvent("vor Driver " + System.currentTimeMillis());
DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
logEvent("vor conn " + System.currentTimeMillis());
conn = DriverManager.getConnection("jdbc:oracle:thin:@"+strOracleServer, strOracleUser, strOraclePwd); //Aufbau Verbindung
if (conn.isClosed())
logEvent("Oracle Connection is not open yet.");
stmt = conn.createStatement();
logEvent("Datenbankanbindung an ACAT erfolgreich hergestellt");
// Ermitteln der zu überprüfenden Dokumente
terminalView = dbCurrent.getView("(luACATAbfrage)");
terminalDoc = terminalView.getFirstDocument();
while (terminalDoc != null) {
nextDoc = terminalView.getNextDocument(terminalDoc);
checkyyyenInfo(terminalDoc);
terminalDoc.recycle();
terminalDoc = nextDoc;
} //Ende While
logDoc.save(true,false);
stmt.close();
conn.close();
} catch(Exception e) {
e.printStackTrace();
}
System.gc();
} //Schließen Main
public void checkyyyenInfo(Document updateDoc)
{
try {
logEvent("vor Abfrage " + System.currentTimeMillis());
String common = updateDoc.getItemValueString("zzzName");
rs = stmt.executeQuery ("SELECT * FROM " + strOracleView + " WHERE zzzName='"+common + "'");
logEvent(common + System.currentTimeMillis());
if (rs.next())
{
String strxxxstelle = new String(rs.getString(3));
String stryyyenstelle = new String(rs.getString(4));
String strOldyyyenstelle = updateDoc.getItemValueString("yyyenstelle");
String strOldxxxstelle = updateDoc.getItemValueString("xxxstelle");
boolean result1 = strOldyyyenstelle.equals(stryyyenstelle );
boolean result2 = strOldxxxstelle.equals(strxxxstelle );
if ( result1 == false|| result2 == false)
{
fillyyyenInfo (updateDoc, stryyyenstelle, strxxxstelle);
}
}
rs.close();
}
catch(Exception e) {
e.printStackTrace();
}
}// Schliessen checkyyyenstellenInfo
public void fillyyyenInfo(Document updateDoc, String stryyyenstelle,String strxxxstelle)
{
try {
String common = updateDoc.getItemValueString("zzzName");
updateDoc.replaceItemValue("xxxstelle",stryyyenstelle);
updateDoc.replaceItemValue("yyyenstelle",strxxxstelle);
logEvent(common + System.currentTimeMillis());
updateDoc.save(true,false);
}
catch(Exception e) {
e.printStackTrace();
}
}// Schliessen FillyyyenstellenInfo
public void logEvent(String eventToBeLogged)
{
try {
logCount++;
logItem.appendToTextList(eventToBeLogged);
if (logCount > 200)
{
logDocCount++;
logCount=0;
logDoc.save(true,false);
logDoc = dbCurrent.createDocument();
logDoc.replaceItemValue("Form","Log");
logDoc.replaceItemValue("Lauf","Lauf vom: " + cal.get(Calendar.DATE)+"."+(cal.get(Calendar.MONTH)+1)+"."+cal.get(Calendar.YEAR)+" " + cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" Uhr " + logDocCount + ". Teil");
logDoc.replaceItemValue("Log","");
logItem = logDoc.getFirstItem("Log");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
flaite:
Hi,
einiges ist suboptimal an dem Code.
Am besten du baust dir erstmal ein lesbares Logging für ad hoc Zeitmessungen ins log.
Eigenschaft: (unter Session session=null; )
--- Code: ---long lastMillis = System.currentTimeMillis();
--- Ende Code ---
Methode: (vor letzter schliessenden Klammer)
--- Code: ---public long getDifMillis() {
long newMillis = System.currentTimeMillis();
long dif = newMillis - lastMillis;
lastMillis = new Millis;
return dif;
}
--- Ende Code ---
Dann kannst du im Code das für Logstatements verwenden.
ein guter Kandidat ist hier:
--- Code: ---while (terminalDoc != null) {
nextDoc = terminalView.getNextDocument(terminalDoc);
checkyyyenInfo(terminalDoc);
terminalDoc.recycle();
terminalDoc = nextDoc;
}
--- Ende Code ---
Vor dem recycle:
--- Code: ---logEvent("processing doc " + terminalDoc.getUniversalID() + " Zeitdif->" + getDifMillis + " milliseconds");
--- Ende Code ---
Ich vermute, dass am meisten Zeit für die ständig wiederholten Selects verbrauchst. Am meisten Optimierungsmöglichkeiten seh ich im SQL.
Vermutlich kannst du das ganze auf ein Statement verkürzen so der Art:
--- Code: ---SELECT spaltenDieDuBenötigstMitKommaGetrennt FROM " + strOracleView + " WHERE zzzName IN zusammenbauenDerBenötigtenWerteAlsKommaGetrennteListe.
--- Ende Code ---
Kann letzteres noch genauer ausführen, hab aber jetzt keine Zeit.
UND verwende die Klasse PreparedStatement und nicht Statement. Allein schon aus Sicherheitsgründen!
Was machst du, wenn Leute in dem Feld zzzname sowas wie "';Delete From eineTabelleInDerOracleDB eingeben ;D
DAU-in:
Pro select werden 7 - 8 sekunden verbraten.
Das ist irgendwie ne ganze Menge :-X
DAU-in:
--- Zitat von: Pitiyankee am 13.05.09 - 11:14:59 ---
Ich vermute, dass am meisten Zeit für die ständig wiederholten Selects verbrauchst. Am meisten Optimierungsmöglichkeiten seh ich im SQL.
Vermutlich kannst du das ganze auf ein Statement verkürzen so der Art:
--- Code: ---SELECT spaltenDieDuBenötigstMitKommaGetrennt FROM " + strOracleView + " WHERE zzzName IN zusammenbauenDerBenötigtenWerteAlsKommaGetrennteListe.
--- Ende Code ---
--- Ende Zitat ---
Die Liste: ist das jetzt ein String, der mit Komma getrennt die Werte enthält?
Oder läuft das auf einen Vektor hinaus?
flaite:
Pro Select? Das heisst der Agent führt mehrere Select statement durch und JEDES select dauert 7 bis 8 Sek?
Das ist nicht normal. Red mal mit einem DB Admin. Teste es mit einem SQL Client wie SQLPlus oder Squirrel von deinem Arbeitsplatz, ob es da auch so lange dauert, etc.
Eventuell - falls die Oracle.jar an den Agenten angehängt ist, kannst du auch mal versuchen die Oracle Treiber jar in das /lib/ext Verzeichnis des Servers tun.
Select spaltenliste!!! in ('werta', 'wertB', ...)
Hab lang kein Oracle mehr gemacht, sollte aber da auch gehen.
Gruß Axel
Navigation
[0] Themen-Index
[#] Nächste Seite
Zur normalen Ansicht wechseln