| |
VB.NET - Ein- und UmsteigerDatenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: lastyle | Datum: 11.11.14 23:58 |
| Hallo zusammen,
da ich mich mit so einem "grossprojekt" noch nicht beschftigt habe frage ich bevor ich vollkommen falsch anfange lieber ersteinmal nach dem bestmöglichen Lösungsansatz.
Aufgabenstellung ist unter Visual Studio 2010:
Ich habe eine CSV Datei mit ca 3,8 Millionen Zeilen. Diese Zeilen beinhalten Dateinamen
Aus einer Containerdatei erstelle ich per shellexecute eine Datei mit dem Namen tmp.lst. In dieser tmp.lst stehen wiederrum Dateinamen in Anführungszeichen. Nun möchte ich für jeden Dateinamen aus der tmp.lst eine Suche starten innerhalb der CSV Datei. Falls der Dateiname gefunden wird kann nach dem nächsten Namen gesucht werden da er ja bereits vorhanden ist. Sollte ein Dateiname nicht in der CSV vorhanden sein möchte ich den Namen des Containers in eine Neue Liste schreiben.
Soweit ist das ja auch alles kein Problem, nur was nehme ich am besten für die CSV Datei um sie schnellstmöglich zu durchsuchen ? Soweit ich das richtig verstanden habe ist ja bei Listview oder Data Grid bei 2,xxx Mio einträgen schluss. Und ich möchte die CSV eigentlich beim Start in den Speicher Laden um die Festplattenzugriffe zu minimieren.
Danke schonmal
Beitrag wurde zuletzt am 11.11.14 um 23:59:49 editiert. | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Manfred X | Datum: 12.11.14 00:19 |
| Hallo!
Zunächst einen Sortierzeiger für die Zeilen in der CSV aufbauen
und dann binäre Suche auf der Basis des Zeigers einsetzen ...
Falls genügend Hauptspeicher im PC vorhanden ist, um alle Daten
zu laden, kann das über eine generische Liste laufen.
| |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: lastyle | Datum: 12.11.14 20:46 |
| Hallo Manfred,
gibts da irgenwo einen Beispiel Source zu ?
Gruß Mario
| |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Manfred X | Datum: 12.11.14 20:58 |
| Schau Dir mal diese Funktion an ...
''' <summary>Klasse zur Aufbewahrung eines SortierSchlüssels und
' zugehörigem Index
''' </summary>
Public Class SortItem
Implements IComparable(Of SortItem)
Public Property FileSortString As String
Public Property FileRowIndex As Integer
Public Function CompareTo(other As SortItem) As Integer _
Implements System.IComparable(Of SortItem).CompareTo
Return Me.FileSortString.CompareTo(other.FileSortString)
End Function
End Class
''' <summary>Aufbau eines Sortier-Zeigers zu Zeilen einer CSV-Datei</summary>
''' <param name="CSVFile">Pfad einer CSV-Datei</param>
''' <param name="TextEncoder">Text-Encoding (meist: UTF8)</param>
''' <param name="columnindex">Array mit nullbasierten Indices der
''' hierarchischen Sortierspalten (0=höchste Hierarchie-Stufe)</param>
''' <param name="columnlength">Array mit Angaben zur Länge der
' Sortier-Teilschlüssel</param>
''' <param name="sortlst">sortierte Liste mit den Sortierschlüsseln und
' den FileRowIndices</param>
Public Function FillSortList(ByVal CSVFile As String, _
ByVal TextEncoder As System.Text.Encoding, _
ByVal columnindex() As Integer, _
ByVal columnlength() As Integer, _
ByRef sortlst As List(Of SortItem)) As Integer
sortlst = New List(Of SortItem)
If Not IO.File.Exists(CSVFile) Then Return -1
If Not IO.Path.GetExtension(CSVFile).ToLower = ".csv" Then Return -1
If columnindex Is Nothing OrElse columnindex.Length = 0 Then Return -1
If columnlength Is Nothing OrElse _
Not columnlength.Length = columnindex.Length Then Return -1
Dim mincolumnindex As Integer = _
Aggregate ind As Integer In columnindex Distinct Into Min()
If mincolumnindex < 0 Then Return -1
Dim maxcolumnindex As Integer = _
Aggregate ind As Integer In columnindex Distinct Into Max()
If (Aggregate ind As Integer In columnlength _
Distinct Into Min()) < 3 Then Return -1
Try
Dim fri As Integer = -1, fss As String = "", content As String = ""
Using sr As New IO.StreamReader(CSVFile, TextEncoder)
While Not sr.EndOfStream
Dim fields() As String = sr.ReadLine.Split(";"c)
If fields.Length > maxcolumnindex Then
fri += 1 : fss = ""
For i As Integer = 0 To columnindex.Length - 1
content = fields(columnindex(i)).ToString.ToLower
'Länge des Inhalts an Vorgabe anpassen
Dim adds As Integer = columnlength(i) - _
content.Length
If adds > 0 Then
content &= New String(" "c, adds)
ElseIf adds < 0 Then
content = content.Substring(0, columnlength(i))
End If
fss &= content & " "
Next i
sortlst.Add(New SortItem With _
{.FileRowIndex = fri, .FileSortString = _
fss})
End If
End While
End Using
If sortlst.Count = 0 Then Return 0
sortlst.Sort()
Return sortlst.Count
Catch ex As Exception
Return -1
End Try
End Function Anwendungsbeispiel:
Dim lst As New List(Of SortItem)
'Liste mit Sortierschlüsseln füllen und sortieren
Dim index As Integer = FillSortList("C:\daten\sortable.csv", _
System.Text.Encoding.UTF8, {0, 1}, {5, 3}, lst)
'Suche nach einem Schlüssel
index = lst.BinarySearch(New SortItem With {.FileSortString = "xxxx yyy "}) | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: effeff | Datum: 13.11.14 12:16 |
| Ich würde die Daten in eine DataTable schreiben, für die ich dann einen Primary Key kreiere. Danach können die Daten per DataTable.Find schnell und unkompliziert gefunden werden. Die DataTable kannst Du dann als XML speichern.
EALA FREYA FRESENA | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Manfred X | Datum: 13.11.14 12:42 |
| Hallo!
So weit mir bekannt, wendet die "Find"-Methode der Datarows-Auflistung
auch bei Nutzung des Primaryschlüssels eine O/N-Suche an.
Das wäre im Hinblick auf Effizienz bei langen Listen und einer
Vielzahl von Such-Operationen nicht mit binären Suche in einer
sortierten Liste vergleichbar (Log O/N).
Hast Du dazu andere Infoemationen?
3,8 Millionen Datensätze gehören nicht in eine XML-Datei. | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Manfred X | Datum: 13.11.14 14:51 |
| XML ist entwickelt worden, um zusätzlich zu den Daten eine
Struktur (Schema, Formate usw.) zu speichern, die für Menschen
lesbar sein soll (Text-Datei) und sich z.B. auch für DataBinding eignet.
Das führt dazu, daß das "Byte-Volumen" einer XML-Datei gewöhnlich erheblich
größer ist als das einer - mit entsprechenden Daten gefüllten - CSV-Datei.
Eine Optimierung (Effizienz) von Datensatz-Zugriffen ist bei XML
nicht das Ziel. Mehr als einige zehntausend Datensätze sollte man nicht
im XML-Code speichern. Falls keine Datenbank verfügbar ist, kann man
die reinen Daten in einer CSV speichern und erforderliche ergänzende
Angaben zu den Spalten der CSV-Zeilen z.B. in einer separaten Hilfsdatei
hinterlegen. | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: lastyle | Datum: 16.11.14 12:58 |
| Ich bin noch am Hauptprogramm am feintunen bevor ich mit der Intregation beginnen werde.
Aber so als Info zwischendurch.
Die CSV Datei ist 222MB Gross mit derzeit 3,75 Mio Linien (Datensätzen) mit unterschiedlicher Länge.
Ich glaub als XML würd das Ding einfach zu gross.
| |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Chris7483 | Datum: 21.11.14 12:01 |
| Schlagt mich jetzt bitte nicht, aber warum keine SQLCE-Datei einfügen und die Daten darin halten? | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Manfred X | Datum: 21.11.14 13:27 |
| Hallo!
Auch eingebettete Datenbanken haben Grenzen.
Bei einer größeren Anzahl von voneinander unabhängigen
Such-Operationen ist für eine effiziente Strategie die
Art der Datenquelle kaum bedeutsam.
Man wird im Hauptspeicher sortierte Such-Schlüssel für die
Sätze erstellen und darauf binäre Suche einsetzen. | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Chris7483 | Datum: 21.11.14 21:29 |
| Klar, für eine effiziente Suche nicht... Zum speichern aber eher als ne xml-Datei. Bis 4 GB macht sie es ja mit... | |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Christoph1972 | Datum: 22.11.14 09:38 |
| Ich würde versuchen die Datei auf einen SQL-Server zu bringen. Da sind 4 Millionen Datensätze nicht das Problem. Ich designe gerade ein Datenbank, die bis zu 650 Millionen Datensätze bereitstellen soll. Aktuell habe ich 200 Millionen Dummys in der DB und ein Select Command dauert aktuell 17 Sekunden, das finde ich in anbetracht der Datenmenge recht ansprechend. By the way: Du solltest nich Millionen von Datensätzen in ein Grid packen, die müssen nach und nach geladen werden.
Gruß
Christoph
| |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Manfred X | Datum: 22.11.14 10:13 |
| Ja, klar!
Aber es geht in diesem Thema nicht ums Speichern großer Datenmengen,
sondern um die effiziente Gestaltung von Such-Operationen.
Zu prüfen wäre eventuell, wie rasch solche Operationen durch Nutzung
eines geeigneten Datenbank-Index per SQL-Server ausgeführt werden können.
| |
Re: Datenbank/Satz suche mit fast 4 Millionen Zeilen | | | Autor: Christoph1972 | Datum: 22.11.14 10:29 |
| Mir ging es auch nicht um das Speichern der Daten, das ist nur ein positiver Nebeneffekt, sogar mit integrierter Datensicherung. Wie "rasch" so eine Operation ausgeführt wird, hatte ich doch erwähnt. Ich finde die Performance von dem SQL-Server für die Datenmengen jedenfalls überzeugend.
Gruß
Christoph
| |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
TOP! Unser Nr. 1
Neu! sevDataGrid 3.0
Mehrspaltige Listen, mit oder ohne DB-Anbindung. Autom. Sortierung, Editieren von Spalteninhalten oder das interaktive Hinzufügen von Datenzeilen sind ebenso möglich wie das Erstellen eines Web-Reports. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|