Laden...

Datenzuweisung dauert zu lange

Erstellt von Tossi65 vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.456 Views
T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 11 Jahren
Datenzuweisung dauert zu lange

Hallo Leute,
ich verstehe es einfach nicht. Ich hole aus einer MySQL Datenbank mittels Abfrage meine Datensätze und schreibe diese in eine DataTable.

Dann hole ich für jeden Eintrag in der DataTable noch zuätzliche Details per Abfrage.


                    foreach (DataRow r in dt.Rows)
                    {

                        SQL = "select * from tabelle where id = " +  r["twa_code"].ToString();

                        using (MySqlCommand cmd = new MySqlCommand(SQL, ACon))
                        {
                            using (MySqlDataReader dr = cmd.ExecuteReader())
                            {
                                while (dr.Read())
                                {
                                    int a = dt.Columns.IndexOf("part_nr_twa");
                                    int b = dr.GetOrdinal("part_nr_TWA");
                                    //r[a] = dr[b];
                                    //r["part_nr_rim"] = dr["part_nr_rim"];
                                    //r["part_nr_tyre"] = dr["part_nr_tyre"];
                                    //r["part_nr_valve"] = dr["part_nr_valve"];
                                    //r["tyre_manufacturer"] = dr["tyre_manufacturer"];
                                    //r["rim_manufacturer"] = dr["rim_manufacturer"];
                                }
                                dr.Close();
                                dr.Dispose();
                            }
                            cmd.Dispose();
                        }

Nun das kuriose: diese Zuweisung von datareader zu Datarow der Datatable dauert sehre lange. Ich dacht erst, es dauert so lange dass die Row als auch Datareader den Index der Spalte zu finden. Deshalb habe ich versucht den Index vorher zu ermitteln. Das war es nicht, aber wenn ich die Zuweisung r[a] = dr**; auskommentiere vervielfacht sich die Geschwindigkeit. Wie kann ich die Zuweisung anders gestalten??

Danke Tossi

106 Beiträge seit 2011
vor 11 Jahren

Hallo Tossi65,

kann es sein das du mit "dr**" auf eine Lazy-Property zugreifst und er sich die Daten erstmal noch aus der DB holen muss? Wenn ja, dann musst du die Sachen nur Eager laden.

MfG
Rabban

2.891 Beiträge seit 2004
vor 11 Jahren

Wo ich deine Where-Bedingung so sehe: Bitte dringend mal [Artikelserie] SQL: Parameter von Befehlen angucken (und anwenden).

Warum machst du...


dr.GetOrdinal("part_nr_TWA");
dr[b];

...und nicht...


dr["part_nr_TWA"];

Ansonsten:
Wie groß ist der Inhalt von part_nr_twa?
Ist die Zuweisung an r[a] langsam oder das Auslesen aus `dr**[/tt]?
Wahrscheinlich läuft es auch auf ein N+1-Problem hinaus.

R
69 Beiträge seit 2009
vor 11 Jahren

Hi,

um die Sache zu beschleunigen, würde ich die Tabellen über ein View verknüpfen und dann den View auslesen, damit sparst du Selects auf die DB, die Zeit kosten.

Gruß Ron

F
115 Beiträge seit 2012
vor 11 Jahren

Hi,

das ganze dauert so lange, weil da Du für jedes einzelne Element eine eigene DB-Verbindung aufbaust (Overhead Verbindungsaufbau), dann einzelne Datensätze abfragst (synchrone SQLs), das SQL nicht per Parameter Variabilisierst (Schlecht für den Optimizer) und alle Spalten selektierst, auch wenn Du möglicherweise nicht alle brauchst (verhindert Index-only Zugriffe).

Falls dt auch aus der gleichen Datenbank kommt solltest Du die Tabellen am besten Joinen (geht z.B. auch mit einer View, aber auch ohne). Wenn nicht kannst Du auch alle Daten aus der Tabelle in eine DataTable laden und per Linq Joinen.

Allerdings halte ich die Schleife auch für etwas komisch; Jede Datarow r bekommt nacheinander die Werte aller Rows von dr zugewiesen! Der Sinn erschließt sich mir nicht. Sollten nicht die für jede Row von dr eine neue Row von r erzeugt werden (eben ein inner join)?

Gruß
f-igy

4.941 Beiträge seit 2008
vor 11 Jahren

Hallo Tossi65,

es geht mittels der Klasse DataAdapter viel einfacher:


MySqlDataAdapter = new MySqlDataAdapter("SELECT * FROM TableName", connectionstring)
DataTable dataTable = new DataTable();
MySqlDataAdapter.fill(dataTable);

Und für verknüpfte Tabellen ist, wie schon geschrieben, das Stichwort: Inner joins, z.B.


SELECT * FROM TableName1, TableName2 where TableName1.Id1 = TableName.Id2

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 11 Jahren

Danke für die schnellen Antworten, aber ihr liegt daneben.

@dN!3L

das habe ich gemacht, weil ich dachte damit das Problem zu finden.

@f_igy
ich hatte einen join, aber wir nutzen eine MySql Clusterdatenbank und die mögen joins nicht so gerne.
Bei sehr vielen Daten reicht der Speicher nicht. Wir haben extrem viel Daten.
Ich baue nur eine Verbindung vor dem foreach .... auf und es liegt nicht an der Query. Wenn ich
die Zuweisung komplett auskommentiere und trotzdem aber die Daten aus der Datenbank hole,
geht es rasend schnell. Wenn ich aber die Daten zuweise dauert die Zuweisung ca. 2 sek pro Spalte.
Dadurch wir die Abfrage sehr langsam und dauert bei ca. 4000 Datensätze weit über 10 Minuten

Ohne Zuweisung und die gleiche Datenmenge ca. 2 Minten!!!!

Danke Tossi

F
10.010 Beiträge seit 2004
vor 11 Jahren

Dann liegt es an deiner DataTable dt.
Ist die vielleicht an ein Control gebunden?
Dann wird nämlich bei jedem zuweisen dieses Control refreshed.

Ansonsten, "SELECT *" ist sehr ineffectiv, zumal du ja die Spaltennamen kennst.

Gelöschter Account
vor 11 Jahren

dito. Das Select* Statement in jedem Durchlauf deiner Schleife neu auszuführen ist ganz übler Bullshit. Wenn du diese Zeile in den äusseren Scope verlagerst(über das foreach) ist das ganze Problem wohl gelöst.

F
10.010 Beiträge seit 2004
vor 11 Jahren

Du hast anscheinend nicht gesehen das er da für jede Row neue Daten anfordert.

@Tossi65:
http://www.clusterdb.com/mysql/dramatically-increased-mysql-cluster-join-performance-with-adaptive-query-localization/

T
Tossi65 Themenstarter:in
83 Beiträge seit 2010
vor 11 Jahren

Danke Euch allen, dass habe ich nun hinbekommen. Das Daten holen ist nun ein klacks.

Nun hat sich das Problem verlagert. Ich lade alle Daten in ein DataTable.
Wenn ich fertig bin, mache ich folgende Zuweisung:
GV.DataSource = DatatTable

Bei ca. 5000 Datensätzen dauert das Anzeigen ca. 3 Minuten: Kann ich das ändern???
In Delphi gibt es die Verzögerung nicht!

Danke Tossi

F
10.010 Beiträge seit 2004
vor 11 Jahren