2010-09-07 5 views
6

Wir verwenden ODP.NET, um Abfragen auf Oracle-Datenbanken durchzuführen, und normalerweise funktioniert es gut. Es gibt eine bestimmte Datenbank und eine bestimmte Ansicht in dieser Datenbank, aber wir können eine Abfrage von .NET einfach nicht abschließen. Zum Beispiel:Oracle-Abfrage ist langsam (oder fehlschlägt) von .NET-App aber ist schnell von SQL Developer

SELECT some_varchar_field FROM the_view WHERE ROWNUM < 5; 

Wenn ich diese Abfrage aus Oracle SQL Entwickler auszuführen, beendet es in weniger als einer Sekunde. Wenn ich eine identische Anfrage von unserer .NET-Anwendung unter Verwendung von ODP.NET mache, hängt es und erzeugt schließlich einen "ORA-03135: Verbindung verlorener Kontakt" Fehler. Ich denke, dass die Beschränkung auf nur wenige Zeilen die Möglichkeit ausschließt, dass es sich um ein FetchSize-Problem handelt.

Es gibt andere Abfragen, die ich erfolgreich ausführen kann, aber sie sind langsamer von unserem Programm als von SQL Developer. Auch hier stelle ich fest, dass SQL Developer anfangs nur Daten für die ersten 50 Zeilen erhält, aber ich denke, dass die ROWNUM-Bedingung das nicht berücksichtigt.

Was könnte anders sein an der Verbindung oder dem Befehl, den Oracle SQL Developer verwendet, im Vergleich zu dem, den unsere Anwendung verwendet, was zu einem Geschwindigkeitsunterschied führen würde?

Leider habe ich keinen Zugriff auf den Server (außer Oracle-Abfragen dagegen auszuführen).

Vielen Dank.

UPDATE: Ich habe die gleiche Abfrage mit Microsoft Oracle Provider versucht und es führt sehr schnell. Leider ist dieser Anbieter veraltet, so dass dies keine langfristige Lösung ist.

Antwort

9

Es hatte nichts mit dem ODP.NET-Provider zu tun. Das Problem war, dass die Bibliothek, die wir zum Erstellen von Verbindungen für uns verwenden (die natürlich nicht von Oracle SQL Developer verwendet wird und die ich nicht verwendete, als ich den Microsoft-Provider ausprobierte), immer die folgenden Anweisungen ausführte:

ALTER SESSION SET NLS_COMP = LINGUISTIC 
ALTER SESSION SET NLS_SORT = BINARY_CI 

Diese machen Oracle case-insensitive. Aber sie machen auch alle konventionellen Indizes unbrauchbar. Da wir in einer View abgefragt hatten, war die Bestellung integriert. Und da wir die Datenbank nicht besitzen, können wir die Indizes nicht linguistisch gestalten, um das Leistungsproblem zu beheben.

Die Möglichkeit, diese Anweisungen in diesem (seltenen) Szenario nicht auszuführen, behebt das Problem.

+0

Im Anhang zu dieser sehr nützlichen Antwort fand ich, dass ALTER SESSION SET NLS_COMP = BINARY ausgeführt; ALTERSITZUNGS-SET NLS_SORT = BINARY; Setzen Sie die Sitzung auf ihre Standardeinstellungen zurück. Sicher, es schaltet die Groß-/Kleinschreibung ein, aber das ist nicht so schlimm wie langsame Abfragen. –

+0

Wie haben Sie festgestellt, dass die von Ihnen verwendete Bibliothek diese Anweisungen ausführt? Ich habe ein ähnliches Szenario: sofort in Oracle Sql Developer, aber ein paar Sekunden von der Anwendung. Das gleiche Szenario auf Sql Server zu testen ist wirklich schneller. Vielleicht fehlt mir eine wichtige Konfiguration. –

4

Immediate Gedanken sind

  1. CLOB, BLOB oder LONG/LONG RAW, die nur für ein paar Zeilen viel Bandbreite erfordert.
  2. Ungültige Daten (zB gibt es Möglichkeiten, ein ungültiges Datum in ein Datumsfeld zu bekommen, was einige Clients verwirren könnte)
  3. "the_table" ist eigentlich keine Tabelle sondern eine Sicht oder etwas mit einer komplexen Ableitung oder hat eine VPD/RLS/FGAC Sicherheitspolitik darauf.
  4. Exotischer Datentyp (Räumlich oder Benutzerdefiniert).

Vorschläge

  1. Explizit die Liste Spalten (zB SELECT a, b, c aus the_table WHERE ROWNUM < 5). Fügen Sie die Spalten nacheinander hinzu, bis sie nicht mehr funktionieren. Das setzt voraus, dass es mindestens eine "einfache" Spalte in der Tabelle gibt.
  2. Überprüfen Sie die Sitzung in v $ Sitzung, um zu sehen, was das Warte-Ereignis ist. Entweder brennt der DB-Server CPU für diese SQL oder wartet auf etwas (möglicherweise den Client).
  3. Überprüfen Sie die SQL in v $ SQL. Gibt es einen oder mehrere Kindercursor? gibt es einen oder mehrere PLAN_HASH_VALUEs. Verschiedene Kindercursor können unterschiedliche Pläne verwenden. Ohne eine WHERE-Klausel außer ROWNUM ist dies ziemlich unwahrscheinlich.
+0

Könnte es auch sinnvoll sein, das Server-Alert-Protokoll zu überprüfen, um zu sehen, ob ein ORA-600 mit dem ORA-03135 für diese Abfrage geliefert wird? –

+0

Ich habe die Frage als Antwort auf Ihre Antwort aktualisiert. Außerdem gibt es nur einfache Felder (das größte Feld ist ein varchar2 (576)), und das Problem tritt auf, selbst wenn ich nur ein Feld auswähle. Sie haben Recht, dass es sich tatsächlich um eine Ansicht handelt. –

0

Bei einem Projekt, an dem ich bei meinem früheren Arbeitgeber arbeitete, benutzten wir odp.net, um mit einer großen Einzelhandels-Systemdatenbank zu sprechen, und wir bekamen Verbindungsfehler.

Es hat viel Mühe gekostet, zu beweisen, aber es endete als korrupter Index in der Oracle-Datenbank, der nur von unserer Abfrage getroffen wurde.Die DBAs führten sie schließlich zu einem Arbeitsschritt des Prozesses zurück, der auf der Sun-Box ausgeführt wurde, als unsere Abfrage ausgeführt wurde. Wir haben keine Art von Anführungshinweisen usw. verwendet, aber wenn wir dieselbe Abfrage in Toad ausgeführt haben, hat es diesen bestimmten Index nicht erreicht. seltsam?? <

1

Eine Ansicht fügt eine andere Größenordnung der Komplexität hinzu. Eine "SELECT-Spalte aus der Tabelle WHERE rownum < 5" hat wahrscheinlich nur einen einzigen EXPLAIN-Plan, der Daten von einem einzelnen lokalen Objekt auswählt.

Für eine Ansicht, die Sie, indem sie die Ansicht Text SELECT TEXT FROM ALL_VIEWS WHERE VIEW_NAME = ...

Es gibt eine Menge, die unterschiedlich sein können zwischen einem ODP.NET und einer SQL Developer-Sitzung gestartet werden soll. Ich würde über NLS-Parameter (wie Datumsformate) und Zeichensatzeinstellungen nachdenken.

Wenn Sie die SQL in v $ sql finden können, können Sie eine DBMS_XPLAN.DISPLAY_CURSOR (sql_id) tun, um die verschiedenen Pläne zu sehen und sehen, ob Sie das Problem identifizieren können.

Verwandte Themen