CListCtrl: Wie setzt man mit LVN_GETDISPINFO die ItemData?
-
estartu schrieb:
Das Daten muss ich wohl trotzdem noch in einen Thread auslagern. Mal schauen wie ich das löse. Das ist nämlich die Bremse, nicht das Anzeigen.

Verstehe ich nicht ganz. Was ist die Bremse? "Das Daten" verstehe ich nicht!
-
Ups, da hatte ich ein Wort vergessen: "Das Daten laden" aus der Datenbank (MSDE) per ODBC (dass das saulahm ist, habe ich zu spät erfahren) ist die Bremse.
Grob kann man sagen: pro 100 Zeilen 1 Sekunde.
Ich muss wohl nochmal gucken, ob ich ein paar Querys reduzieren kann. Da werden nämlich noch zig Tabellen querverbunden.Man kann trotz der langen Ladezeit prima damit arbeiten, hab ich heute ja (das Modul geht gerade in Betrieb, daher zum ersten Mal so viele Datensätze).
Man darf nur nicht auf die Anzeige warten, einfach tippen.
-
Wichtig bei MSDE und MS-SQL Server. Es ist nicht das Laden der Daten was normalerweise Geschwindkeit kostet, sondern der Query selber. Die Daten rauschen normalerweise nur so rein, wenn mal das Ergebnis da ist.
Wichtig ist auch nur die Daten zu übertragen, die auch benötigt werden. Also alle unnötigen Spalten unbedingt weglassen.Per OLE-DB und MSDE/MS-SQL komme ich auf bis zu 20000 Zeilen pro Sekunden über ein normales Netzwerk, wenn die Datensätze kurz sind.
Welcher Cursor-Typ wird verwendet, dass spielt natürlich auch eine Rolle?
-
Also, ich arbeite mit CRecordsets, die der Assistent erstellt hat.
Kann ich den cursortyp da nachgucken? Ich weiß nämlich leider nicht so genau, was du meinst.Und nur die Spalten, die ich wirklich brauche? Dann würde sich wohl doch ein View anbieten. Das könnte wirklich deutlich schneller sein, ich habe eine ziemlich vermurkste Ladestruktur.

-
Du gibst den Cursor Typ beim Open des CRecordsets an.
Der Default verwendet AFX_DB_USE_DEFAULT_TYPE, was darauf hinausläuft das der CRecordset::snapshot verwendet wird (Vorbelegung von m_nDefaultType).
snapshot ist Bidfirektional, da Du die Daten aber wahrschenlich nur einfach durchliest würde CRecordset::forwardOnly auch genügen. Das kan auch noch Geschwindigkeit bringen.
-
Also, die Umstellung auf einen View hat schon mal 2 Sekunden gebracht.
Leider bekomme ich, wenn ich aufm_nDefaultType = forwardOnly;ändere, folgenden Fehler bei einer Abfrage eines anderen Recordsets:
Die Verbindung ist mit Ergebnissen von einem anderen hstmt belegt.

Der Fehler kommt immer und immer wieder...
-
Du must ja nicht gleich den Default ändern, Du kannst ja auch beim Open angeben, welchen Modus Du möchtest!
-
Okay, das habe ich jetzt mal gemacht, aber das hilft nicht.

Der Fehler kommt trotzdem.... oh, ich hab das Abschicken vergessen. 10 Minuten suchen später:
Ich öffne das Recordset jetzt erst, wenn alle anderen Daten geladen sind, nun kommt der Fehler nicht mehr.Jetzt brauchen die 800 Zeilen gut 1 Sekunde, damit kann ich erstmal wieder leben.

Vielen Dank Martin.

PS: Falls du weißt, was der komische Fehler war, würde ich das trotzdem gerne wissen.

PPS: Ich bin auch wieder von der virtuellen Liste weg, da ich dann das CSortListCtrl nicht mehr nutzen könnte.
-
Zu der Fehlermeldung: Kann es sein, dass Du mehere Queries zur gleichen Zeit offen hast?
Zum Sortieren: Nun das geht auch. Allerdings musst Du dann selber Deine Daten in Deinem Bereich sortieren. Ein Invalidate genügt dann. Ich verwende eine eigene Klasse für solche Datenbankzugriffe die ich auf ein virtuelles CListCtrl abbilde. Der Durchsatz ist gigantisch. Selbst so 1Mio Datensätze sind leicht und locker verarbeitet.
-
Martin Richter schrieb:
Zu der Fehlermeldung: Kann es sein, dass Du mehere Queries zur gleichen Zeit offen hast?
Ja, aber auf verschiedene Tabellen... achne, die sind ja im View drin. Okay, Denkfehler meinerseits. Ich habe lange nicht mit Views gearbeitet.
Zum Sortieren: Nun das geht auch. Allerdings musst Du dann selber Deine Daten in Deinem Bereich sortieren. Ein Invalidate genügt dann.
Wie macht man das dann? Jedes Sortieren ein Query?
Ich müsste dann "nur" rausfinden, nach welcher Spalte und wie rum sortiert werden soll. Das habe ich schon mal versucht und habe dann irgendwann abgebrochen.
Ich verwende eine eigene Klasse für solche Datenbankzugriffe die ich auf ein virtuelles CListCtrl abbilde. Der Durchsatz ist gigantisch. Selbst so 1Mio Datensätze sind leicht und locker verarbeitet.
Das klingt gut. Ich hatte mir sowas gestern auch überlegt, aber erstmal wegen dem Sortierproblem verworfen.

-
Hast du keinen Tip zum Sortieren? Oder ist das Firmengeheimnis?

-
estartu schrieb:
Hast du keinen Tip zum Sortieren? Oder ist das Firmengeheimnis?

Nein! Du hast mehrere Ansätze:
1. Variante: Du hast sowieso alle Daten in Deinem Speicher. Da die virtuelle Liste dies benötigt, kannst Du einfach un primitiv Deine Daten per Quicksort durchsortieren.2. Varinate (Komplex): Deine Queries liefern nur IDs der Ergebnissätze (kompliziert wenn es sich um Daten aus Joins handelt). Diese IDs werden immer auch in einer eigenen temporären SQL Tabelle mitgeführt. In einem kleinen Cache werden die eigentlichen Daten bei Bedarf gelesen aus der DB. Ein Sort ist dann nichts weiter als ein umsortieren der IDs in der temporären Tabelle.
Hört sich schwierig an ist aber immens flexibel.