Programm fängt an "langsam" zu werden.

Gast #5265492
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?
Gast #5265564
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)
Gast #5265612
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?
Gast #5265643
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!
Gast #5265645
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.
Gast #5265761
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
Gast #5265843
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
Gast #5266780
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.
Gast #5268916
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren