Forum: PC-Programmierung Programm fängt an "langsam" zu werden.


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Andreas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe ein kleines Programm welches echt super funktioniert, aber 
leider wird das ziemlich schnell langsam...

Der Fehler ich "reproduzierbar" ... sicherlich Erzeug ich irgendwo im 
Hintergrund Daten ohne ende oder so, evtl. hat jemand einen Tipp für 
mich.

ich habe eine kleine Methode welche einen Datenbankabruf macht und 5 
Zeilen aus der Datenbank holt... <- da hier Millionen schlecht 
indizierte Daten sind, dauert das ganze fast 5 Sekunden (ist aber nicht 
das Problem).

1
        public static DataTable Sql2DataTable(string tns, string query)
2
        {
3
            DataTable result = new DataTable();
4
            try
5
            {
6
                using (OracleConnection dbConnection = new OracleConnection(tns))
7
                {
8
                    OracleCommand command = dbConnection.CreateCommand();
9
                    command.CommandText = query; 
10
                    dbConnection.Open();
11
                    using (OracleDataReader reader = command.ExecuteReader())
12
                    {
13
                        result.Load(reader);
14
                    }
15
                    dbConnection.Close();
16
                }
17
            }
18
            catch (Exception ex)
19
            {
20
                MessageBox.Show(ex.Message);
21
            }
22
            return result;
23
        }

anschließend werden die Daten über ein Binding direkt an ein eine 
DataTable gebunden...

als Hauptprogramm habe ich eine DataTable mit ~200 Zeilen, wenn man eine 
Zeile anklickt, wird diese "geöffnet" und es erscheint eine 
"Mini-Tabelle" in welcher die 5 Zeilen geladen werden...

Das Laden mache ich (wie oben bereits erwähnt) über ein Binding im 
DataGrid:
ItemsSource="{Binding Path=ID, Converter={StaticResource dataReader}, 
ConverterParameter=prm,IsAsync=True,FallbackValue='Please Wait'}"

Das funktioniert das 1. mal perfekt! Das 2. mal (also wenn ich eine 2. 
Datenzeile anklicke) etwas langsamer und das 3. mal merkt man schon 
deutlich, dass z.B. das Scrollen durch die Hauptliste langsamer wird 
(dabei habe ich einen i7 und 16GB RAM).

kann man hier schon eine Aussage treffen? oder welche Informationen 
müsste ich noch liefern?

von Daniel -. (root)


Bewertung
-1 lesenswert
nicht lesenswert
Dann zeig doch das Hauptprogramm und nicht die irrelevante Funktion

von Andreas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
was willst du denn sehen?

mehr code gibt es nicht...

das Hauptprogram hat damit rein GARNICHTs zu tun... wie schon gesagt, 
das geht über ein BINDING <- und das läuft auch schief, wenn das 
Hauptprogramm nicht existent ist... (mal abgesehen von den Daten für die 
Datenbank TNS & Query)

von Andreas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Fehler gefunden... leider weiß ich noch nicht wie ich es lösen kann...

Das Binding löst öfters einen "DB" abruf aus... und immer wenn der 
DB-Abruf ausgelöst wird, dauert es 5 sekunden bis die werte da sind...

das macht er komischerweise beim 1. mal nicht, beim 2. mal selten und ab 
den 3. mal sehr oft.

Wie kann ich mein Binding Cachen oder wie kann ich eine DataTable 
Cachen?

von Ingo D. (ingo2011)


Bewertung
0 lesenswert
nicht lesenswert
Hi ,

zeig doch mal Dein Select (query). Wenn ich oben lese "hier Millionen 
schlecht indizierte Daten" , dann muss man hier erstmal ansetzen das 
Design zu ueberarbieten ... wenn jedesmal ein Full table scan gemacht 
werden muss ist das klar, das es langsam ist ...

Gruß Ingo

von Der Andere (Gast)


Bewertung
0 lesenswert
nicht lesenswert
By the way, wenn in den Aufrufen
  reader = command.ExecuteReader()
  result.Load(reader);
eine Exception geworfen wird, dann bleibt deine Connection endlos offen.
Das close() gehört in ein finally!

von Andreas (Gast)


Bewertung
0 lesenswert
nicht lesenswert
keine Angst, der Select ist perfect

ich bin Oracle Datenbankdeveloper... an den kann man nichts mehr 
verbessern und außerdem läuft dem im SQL-Developer gleichschnell!

die 5 Sekunden sind und bleiben...
=> und selbst wenn es 0.5 Sekunden wären, würde das Tool amok laufen, 
wenn ständig neue Daten erfragt werden, obwohl die Informationen bereits 
gegeben sind.

=> hier muss das Binding angepasst werden oder die Daten gecached...

Beitrag #5265661 wurde von einem Moderator gelöscht.
Beitrag #5265671 wurde von einem Moderator gelöscht.
von Der Andere (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Andreas schrieb:
> Das Binding löst öfters einen "DB" abruf aus... und immer wenn der
> DB-Abruf ausgelöst wird, dauert es 5 sekunden bis die werte da sind...
>
> das macht er komischerweise beim 1. mal nicht, beim 2. mal selten und ab
> den 3. mal sehr oft.
>
> Wie kann ich mein Binding Cachen oder wie kann ich eine DataTable
> Cachen?

Indem du dich an Design Regeln hältst:
https://msdn.microsoft.com/en-us/library/ee658109.aspx

Sorge dafür daß du deine "Sql2DataTable" Methode nur aufrufst wenn du 
wirklich neue Daten brauchst. Wenn du den Aufruf irgendwo im 
Presentation Layer versteckst wo du keine Kontrolle darüber hast:

Andreas schrieb:
> Das Laden mache ich (wie oben bereits erwähnt) über ein Binding im
> DataGrid:

dann musst du dich nicht wundern wenn der Aufruf auch dann geschieht 
wenn du nicht damit rechnest. Also packe die Daten in eine gepufferte 
Struktur die nur dann die Daten durch ein Query auf die Datenbank 
aktualisiert wenn du das für richtig und notwendig hältst. Dein Grid 
erhält dann die Daten über deinen Puffer.

Andreas schrieb:
> keine Angst, der Select ist perfect
>
> ich bin Oracle Datenbankdeveloper... an den kann man nichts mehr
> verbessern

Sorry aber zu dem Spruch fällt mir spontan das hier ein:
https://de.wikipedia.org/wiki/Dunning-Kruger-Effekt

von Walfänger (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Oracle ist eben nicht mehr der Nabel der Welt, wenn es um schnelle 
Datenbanken geht. Es gibt auch welche, die finden die 5aus10^6 Sätze 
über eine nicht-indizierte Spalte in 5ms.

von P. P. (klatschnass)


Bewertung
0 lesenswert
nicht lesenswert
In deinem Quelltext baust du bei jeder Anfrage eine neue 
Datenbankverbindung auf. Das geht manchmal schnell, und oft dauert's ein 
paar Sekunden, weil Oracle wieder alles neu intialisieren muss.

Empfehlenswert wäre, wenn du die Connection nur einmal aufmachst und 
dann für jeden SQL-Request wiederverwendest (pufferst).

Weiterhin empfiehlt sich ein Pooling der Connections, falls du mehrere 
SQLs gleichzeitig parallel an Oracle schickst. Dafür kann man z.B. c3pO 
gut und schnell einbinden.

Gruß Pirx

von abc (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Andreas schrieb:
> Das funktioniert das 1. mal perfekt! Das 2. mal (also wenn ich eine 2.
> Datenzeile anklicke) etwas langsamer und das 3. mal merkt man schon
> deutlich, dass z.B. das Scrollen durch die Hauptliste langsamer wird
> (dabei habe ich einen i7 und 16GB RAM).

Für ausnahmslos jede Programmiersprache gibt es Profiler.

Wie wäre es, wenn du dein Programm mal profilierst?

Beitrag #5267139 wurde von einem Moderator gelöscht.
von stnv (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Andreas schrieb:
>ich habe eine kleine Methode welche einen Datenbankabruf macht und 5
>Zeilen aus der Datenbank holt... <- da hier Millionen schlecht
>indizierte Daten sind, dauert das ganze fast 5 Sekunden (ist aber nicht
>das Problem).

>Das funktioniert das 1. mal perfekt! Das 2. mal (also wenn ich eine 2.
>Datenzeile anklicke) etwas langsamer und das 3. mal merkt man schon
>deutlich, dass z.B. das Scrollen durch die Hauptliste langsamer wird
>(dabei habe ich einen i7 und 16GB RAM).

>das macht er komischerweise beim 1. mal nicht, beim 2. mal selten und ab
>den 3. mal sehr oft.

>ich bin Oracle Datenbankdeveloper

Aus diesen Angaben würde ich folgendes schlussfolgern:

Die OracleDB ist nicht optimal auf dem Rechner eingerichtet. Da hilft 
auch kein Profiling. Dieses würde wahrscheinlich bei diesen Zeiten 
einfach sagen "Fulltablescan".

Die Datenbank hat standartmäßig heute ein dynamisches Speichermanagement 
(ab 10g). Dieses paßt den Speicher und damit die Möglichkeiten den Cache 
zu nutzen schnell wieder zu nichte. Gerade auf nicht sehr stark 
frequentierte "Developer Datenbanken".

Das würde auch die eigentümlichen Geschwindigkeitssprünge erklären.


Aus Sicht der Datenbank:

Ja. Eine Tabelle kann in den Cache kommen. Dies ist standardmäßig nicht 
aktiv. Die Daten altern sehr schnell raus.
(ALTER TABLE ... CACHE)

Wenn hier schon eine 16 GByte Maschine vorliegt dann schenke der 
Datenbank Speicher damit sie cachen kann. Falls es eine Express Version 
(max 1 GByte) ist, dann installiere ein richtige Version, sie kann für 1 
Monat frei genutzt werden. Somit kann die Geschwindigkeitsoptimierung 
mal geprüft werden.
(ALTER SYSTEM ...)

Schalte das dyn. Speichermanagement mal aus. Damit bleibt der Speicher 
durch die DB im Zugriff und es können die Daten aus dem Cache wieder 
verwendet werden.
Daher fixe Speicherverwaltung. Ich würde testweise mal 8GByte zuweisen.
(ALTER SYSTEM ...)

Das sollte im Idealfall dann beim 1. mal durch die physikalischen 
Lesezugriffe etwas langsamer sein. Dann sollten nur noch logische 
Lesezugriffe erfolgen. ergo. Ab dem 2. mal sollten die Daten schneller 
da sein.
Viel wichtiger: Die DB würde "konstanter" reagieren.


Wenn das mal produktiv gehen sollte...
Setz Dich mit einem DBA zusammen und überlegt wie die zukünftige 
Instance der DB aussehen soll. Das Thema Index würde ich auch noch mal 
angehen. Oracle bietet hier einiges. Und dann würde auch ein Profiler 
wieder interessant werden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.