sql server query läuft langsam aus java
Ich habe ein java-Programm, welches eine Reihe von Abfragen in einer sql server-Datenbank. Die erste von diesen, die Abfragen gegen einen Blick zurück über 750k Datensätze. Ich kann die Abfrage über sql server management studio, und ich bekomme Ergebnisse in etwa 30 Sekunden. jedoch, ich startete das Programm in der letzten Nacht. wenn ich überprüft, es an diesem morgen, diese Abfrage hatte noch immer nicht zurückgegeben Ergebnisse zurück an das java-Programm, rund 15 Stunden später.
Habe ich Zugriff auf die Datenbank nur über alles, was ich will, aber ich bin mir wirklich nicht sicher, wie das mit dem debugging beginnen diese. Was soll man tun, um herauszufinden, was die Ursache einer situation wie dieser? Ich bin kein dba, und bin nicht sehr vertraut mit dem sql server-tool-set, also je mehr Details Sie mir geben können, wie das zu tun, was Sie könnte darauf hindeuten würde geschätzt.
heres der code
stmt = connection.createStatement();
clientFeedRS = stmt.executeQuery(StringBuffer.toString());
EDIT1:
Nun ist es schon eine Weile, und habe dadurch abgelenkt, aber das Problem ist wieder da. Ich schaute in die Modernisierung von jdbc-Treiber v 1.2 zu 2.0, aber wir sind fest auf jdk 1.4 und v 2.0 erfordern, jdk 1.5, so dass ein nicht-starter. Jetzt bin ich auf der Suche bei meiner Eigenschaften der Verbindungszeichenfolge. Ich sehe 2, die nützlich sein könnten.
SelectMethod=cursor|direct
responseBuffering=adaptive|full
Derzeit mit der Latenz Problem, ich arbeite mit cursor als selectMethod, und mit dem Standardwert für responseBuffering, die ist voll. Ändern sich diese Eigenschaften, die wahrscheinlich helfen? wenn ja, was wären die optimalen Einstellungen? Ich denke, basierend auf was ich online finden kann, dass die Verwendung einer direct select-Methode und der adaptive response buffering lösen könnte mein Problem. irgendwelche Gedanken?
EDIT2:
Nun, ich endete, eine Veränderung dieser Verbindung, string params, mithilfe des Standard-select-Methode(direkte) und die Angabe der responseBuffering als adaptive. Endet dies funktioniert für mich am besten und verringert die Latenz-Probleme, die ich sah. vielen Dank für all die Hilfe.
- eine Veröffentlichung des Anrufs zu jdbc wäre hilfreich, herauszufinden, was, wenn überhaupt, ist falsch
- Was ist das Java-Programm? Ein code-snippet, wie man Zugriff auf die DB ist wohl nötig. Außerdem ist SQL Server Studio Begrenzung der Ergebnisse (zu, sagen wir, die ersten 1000 Zeilen), die möglicherweise verfälschte Ergebnisse?
- wenn es die Begrenzung der Ergebnisse auf 1k Zeilen, wie kann ich sicher sein, dass es gar nicht?
- Sind SSMS und Ihre Java-app läuft an der gleichen Stelle? Wenn SSMS ausgeführt wird, lokal auf dem SQL-Server, und Ihre Java Anwendung nicht, es ist nicht wirklich ein Vergleich.
- ja, lief die Abfrage über SSMS aus dem gleichen Ort ich bin mit der java-app.
- Sind Sie sicher, dass das ResultSet zurückgegeben hat nicht zu Java überhaupt? Oder ist Java Ewigkeiten braucht, um zu verarbeiten, nachdem es ja schon die erste Zeile?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sicher sein, dass Sie Ihr JDBC-Treiber konfiguriert ist, um eine direkte Verbindung und nicht eine cusror basierten Anschluss. Hier können Sie Ihre JDBC-Verbindungs-URL, wenn Sie nicht sicher sind.
Stellen Sie sicher, dass Sie mit einer forward-only, nur-Lesen-Ergebnismenge (dies ist die Standardeinstellung, wenn Sie nicht die Einstellung).
Und stellen Sie sicher, dass Sie aktualisierte JDBC-Treiber.
Wenn all dies nicht funktioniert, dann sollten Sie sich die sql-profiler und zu erfassen versuchen Sie die sql-Abfrage der jdbc-Treiber führt die Anweisung aus, und führen Sie die Anweisung in das management-studio und sehen, ob es einen Unterschied gibt.
Auch, denn Sie ziehen so viele Daten, dass Sie sollten versuchen, um sicherzustellen, dass Sie nicht mit jedem Speicher/garbage collection Verlangsamungen auf der JVM (in diesem Fall zwar nicht wirklich erklären, die Zeit-Diskrepanz).
Ich hatte ähnliches problem, mit einer sehr einfachen Anfrage (SELECT . AUS . WO = .) die Einnahme von bis zu 10 Sekunden, um eine einzelne Zeile zurückgeben, wenn über eine jdbc-Verbindung in Java, während der Einnahme von nur 0,01 s in der sqlshell. Das problem war das gleiche, ob ich mit dem offiziellen MS-SQL-Treiber oder die JTDS-Treiber.
War die Lösung, um das setup diese Eigenschaft in der jdbc-url :
sendStringParametersAsUnicode=false
Komplettes Beispiel, wenn Sie MS SQL offiziellen Treiber : jdbc:sqlserver://yourserver;instanceName=yourInstance;databaseName=yourDBName;sendStringParametersAsUnicode=false;
Anweisungen, wenn mit verschiedenen jdbc-Treiber und weitere detaillierte infos zu dem problem hier : http://emransharif.blogspot.fr/2011/07/performance-issues-with-jdbc-drivers.html
In meinem Fall hatte ich 30M+ Datensätze in der Tabelle, ich war auf der Suche aus. Die Dauer zum abschließen der Anfrage ging von mehr als 10 Sekunden, um etwa 0.01 s nach der Anwendung der Eigenschaft.
Hoffe, dies hilft jemand !
Scheint es, kann dies nicht angewendet werden, um Ihre spezielle situation, aber ich wollte eine weitere mögliche Erklärung für jemanden der Suche für dieses problem.
Ich hatte gerade ein ähnliches problem, wenn eine Abfrage ausgeführt, die direkt in SQL Server dauerte 1 minute, während die gleiche Abfrage dauerte 5 Minuten durch ein java-vorbereitet statemnent. Ich verfolgte es bis auf die Tatsache, dass es getan wurde, wie eine vorbereitete Anweisung.
Beim ausführen einer Abfrage direkt im SQL-Server, stellen Sie eine nicht-parametrisierte Abfrage, in der Sie kennt alle den Suchkriterien, die zum Zeitpunkt der Optimierung. In meinem Fall, meine such-Kriterien waren ein Datumsbereich ein, und SQL-server in der Lage war, es zu betrachten, zu entscheiden, "das Datum Angebot ist riesig, lasst uns nicht über das Datum index" und dann entschied sich für etwas viel besseres.
Wenn ich die gleiche Abfrage ausführen durch einen java prepared statement, an der Zeit, dass SQL Server optimieren Sie die Abfrage, die Sie noch nicht vorausgesetzt, es werden alle Werte der parameter, so hat es, um eine Vermutung, welcher index zu verwenden. Bei meiner date-Bereich, wenn es optimiert für eine kleine Auswahl und ich gebe es eine große Reichweite ist, wird es langsamer als es sein könnte. Ebenso, wenn es optimiert für eine große Auswahl und ich ihm eine kleine, es ist wieder einmal langsamer als es könnte.
Um dies zu zeigen war ja das problem, als ein experiment, ich habe versucht, ihm Hinweise, was optimiert für die Verwendung von SQL Server "OPTIMIEREN" - option. Wenn ich sagte es mit einem winzigen Zeitraum, meine java-Abfrage (die eigentlich eine Breite Datumsbereich) tatsächlich dauerte doppelt so lange wie bisher (10 Minuten, im Gegensatz zu 5 Minuten vor, und im Gegensatz zu 1 minute in SQL Server). Wenn ich gesagt das es meine genauen Daten zu optimieren, die Ausführungszeit war identisch zwischen den java prepared statement.
So war meine Lösung: codieren Sie die genauen Termine in der Abfrage. Dieser arbeitete für mich, denn es war nur ein one-off-Anweisung. Das PreparedStatement war nicht dazu gedacht, wiederverwendet zu werden, sondern lediglich zur Parametrisierung der Werte zur Vermeidung von SQL-injection. Da diese Termine wurden aus java.sql.Date-Objekt, die ich nicht sorgen über meine Datumswerte mit code injection.
Jedoch für eine Anweisung, die NICHT wiederverwendet werden sollen, harte Kodierung der Daten nicht funktionieren würde. Vielleicht eine bessere option wäre, um mehrere Anweisungen vorbereitet, optimiert für unterschiedliche Zeiträume (für einen Tag, eine für eine Woche, einen Monat, eine für ein Jahr, ein Jahrzehnt oder vielleicht brauchen Sie nur 2 oder 3 Optionen...ich weiß es nicht) und dann für jede Abfrage, führen Sie eine vorbereitete Anweisung, deren Zeitraum am besten entspricht die Reichweite in der eigentlichen Abfrage.
Natürlich funktioniert dies nur gut, wenn Sie das Datum-Bereiche werden gleichmäßig verteilt. Wenn 80% der Datensätze waren im letzten Jahr, und 20% Prozent, die sich über die vorherigen 10 Jahre, dann tut der "multiple Anfragen basierend auf Größe", was vielleicht nicht das beste. Sie müssten optimieren Sie Abfragen basierend auf bestimmte Bereiche oder so etwas. Sie müssten, um das herauszufinden durch Versuch zu einem Fehler.
Ob die Abfrage parametrisiert werden kann eine fehlende parameter oder ein parameter, der gesetzt ist mit der falschen Funktion, z.B. setLong für string, etc.
Versuchen Sie Ihre Abfrage ausgeführt und alle Parameter hardcoded in die Abfrage Körper ohne
?
zu sehen, das ist ein problem.Ich weiß, das ist eine alte Frage, aber da es eines der ersten Ergebnisse bei der Suche nach dieser Frage, die ich dachte, ich würde post, was für mich gearbeitet. Ich hatte eine Abfrage, die dauerte weniger als 10 Sekunden wenn ich in den SQL Server-JDBC-Treiber, aber mehr als 4 Minuten bei Verwendung von jTDS. Ich habe versucht, alle Vorschläge, die hier erwähnt und keiner der es machte keinen Unterschied. Das einzige, was funktioniert hat, ist das hinzufügen dieser auf die URL ";prepareSQL=1"
Sehen Hier für mehr
Ziehen zurück, dass viele Daten benötigt viel Zeit. Sie sollten wahrscheinlich herausfinden, einen Weg, um nicht verlangen, dass viel von Daten in Ihre Anwendung zu jeder Zeit gegeben. Seite die Daten ein oder verwenden Sie lazy loading zum Beispiel. Ohne mehr details was du versuchst zu erreichen, es ist schwer zu sagen.
Die Tatsache, dass Sie schnell, wenn Sie von management studio könnte durch eine falsch zwischengespeicherten Abfrageplan und die out-of-date Indizes (z.B. aufgrund einer hohen import-oder Löschungen). Ist es die Rückkehr aller 750K Datensätze schnell in SSMS?
Versuchen Neuerstellung von Indizes (oder wenn, dass würde zu lange dauern, aktualisieren Sie Ihre Statistiken); und vielleicht ist die Spülung des Prozedur-cache (Vorsicht verwenden, wenn dies ein Produktions-system,...):
DBCC FREEPROCCACHE
Den Debugger zu starten, wäre es gut, um festzustellen, ob das problem in der Datenbank oder in der app. Haben Sie versucht, ändern Sie die Abfrage so, dass es gibt eine viel kleinere Ergebnis? Wenn das nicht zurückgeben, ich würde vorschlagen, targeting die Möglichkeit, die Sie Zugriff auf die DB von Java aus.
Versuchen Sie, den fetch-Größe, die Erklärung und versuchen, selectMethod der cursor
http://technet.microsoft.com/en-us/library/aa342344(SQL.90).aspx
Wir hatten Probleme mit großen Ergebnismengen mit mysql und benötigt, um die Streams der Ergebnismenge, wie in dem folgenden link.
http://helpdesk.objects.com.au/java/avoiding-outofmemoryerror-with-mysql-jdbc-driver
Zitat aus der MS-Adaptive Puffer-Richtlinien:
Und
Mehr sehen: http://technet.microsoft.com/en-us/library/bb879937.aspx
Manchmal könnte es aufgrund der Parameter der Bindung an das query-Objekt.
Ich fand der folgende code ist sehr langsam beim ausführen von java-Programmen.
Einmal Entferne ich den "gelöscht" - parameter und die direkt Anhängen, dass "GELÖSCHT" - string der Abfrage, es wurde super schnell. Kann es daran liegen, dass der SQL-server erwartet, um alle Parameter gebunden, um zu entscheiden, der optimierte plan.
Ich weiß, das ist eine sehr alte Frage, aber da es eines der ersten Ergebnisse bei der Suche nach dieser Frage, die ich dachte, ich sollte post, was für mich gearbeitet.
Hatte ich eine Abfrage, dauerte etwa 3 Sekunden, wenn ich SQL Server Management Studio (SSMS) aber dauerte 3,5 Minuten, wenn die Ausführung mit jTDS JDBC-Treiber über die
executeQuery
Methode.Keines der Vorschlag oben erwähnt war für mich vor allem, weil ich war einfach mit Aussage und nicht Vorbereitete Anweisung. Das einzige, was für mich gearbeitet wurde, um geben Sie den Namen des ersten oder Standard-Datenbank in der Verbindungszeichenfolge an, die den verbindenden Benutzer hat mindestens die db_datareader Mitgliedschaft in Datenbankrolle. Nur die öffentlichen Rolle ist nicht ausreichend.
Hier ist die Beispiel-Verbindungszeichenfolge:
Bitte stellen Sie sicher, dass das Ende
/DefaultDbName
in der Verbindungszeichenfolge angegeben. HierDefaultDbName
ist der name der Datenbank, auf die der angegebene Benutzer-ID für die JDBC-Verbindung, mindestens diedb_datareader
Datenbank-Rolle. Wenn weggelassen, SQL Server standardmäßig diemaster
Datenbank. Wenn die Benutzer-ID verwendet, um die JDBC-Verbindung hat nur diepublic
Rolle in der master-Datenbank, die Abfrage dauert extrem lange.Ich weiß nicht, warum dies geschieht. Ich weiß jedoch, einen anderen Abfrageplan verwendet wird in einem solchen Fall. Ich bestätigte dies mit der SQL Profiler-tool.
Umgebung details:
Dauert es eine ähnliche Menge an Zeit mit SQLWB? Wenn die Java-version ist viel langsamer, dann würde ich prüfen, ein paar Dinge: