| 

.NET C# Java Javascript Exception

1
Hallo,
gibt es eine Möglichkeit, die Größe eines MysqlCommand-Objekts im Speicher (incl. Parameter) in VB zu bestimmen?
Hintergrund: ich weiß von meinem MySQL-Server, dass er max allowed packet=16M hat. Da ich oft tausende von Datensätzen anfügen muss, generiere ich dynamisch einen INSERT INTO mit Parametern [insert into ... (...),(...)]. Nun würde ich mit dem Insert natürlich gerne in die Nähe der 16 MB kommen.
Es stellt sich natürlich die Frage, ob es dann zur Laufzeit nicht evtl. mehr Zeit kostet, die Größe des Objekts zu bestimmen. Ich dachte auch schon darüber nach, die Stringlänge pro Feld in einer Variable zu addieren, aber das ist ja auch relativ ungenau.
06.06.2014
muffi 1,4k 1 9
muffi 1,4k 1 9
Generell stellt sich mir die frage wieso du nicht über den Weg des MySqlBulkLoader gehst und alle Datensätze mit einmal importierst anstatt tausende Insert-Statmenets zu erzeugen.

Anmerkung: In MSSQL kann ich auch ganze DataTables als Parameter binden. Nach ein wenig googlen konnte ich dafür aber keine Entsprechnung in MySQL finden.
Floyd 06.06.2014
Weil der MySQL-Treiber keinen BulkLoader kennt!
muffi 06.06.2014
1
Hier der Source für den BulkLoader http://opensourcejavaphp.net/csharp/mysqlconnectordotnet/BulkLoader.cs.html

Interessant ist die Funktion BuildSqlCommand die letztendlich ein INFILE-Command zusammenbaut.

INFILE-Referenz: http://dev.mysql.com/doc/refman/5.1/de/load-data.html

Ich denke darüber sollte es deutlich schneller und effizienter gehen.

Nur so als Anregung/alternative Lösung.
Floyd 06.06.2014
Muss ich einfach mit einem +1 belohnen, das kannte ich noch nicht. Das ist möglicherweise tatsächlich eine Alternative, setzt aber einen FTP-Zugriff auf den Server voraus, wenn ich das richtig in Erinnerung habe. Auf jeden Fall ein Versuch wert!
muffi 10.06.2014
1 Antwort
0
Dafür konntest du auf die die Methode GC.GetTotalMemory zurückgreifen.
Retrieves the number of bytes currently thought to be allocated. A parameter indicates whether this method can wait a short interval before returning, to allow the system to collect garbage and finalize objects.

Dim preCreate as Long = GC.GetTotalMemory(True)

..SQL-Command erzeugen..

Dim postCreate as Long = GC.GetTotalMemory(True)
Console.WriteLine(postCreate - preCreate)


Eine weitere Möglichkeit wäre die Methode Marshal.SizeOf.
Returns the unmanaged size, in bytes, of a class.


Darüber hinaus gibt es so genannte Memory Profiler wie der ANTS Memory Profiler die du dir mal anschauen solltest wenn die obrigen Lösungen nicht zum Ziel führen.
06.06.2014
Floyd 14,6k 3 9
Floyd 14,6k 3 9
Gar nicht schlecht die Idee. Gleich mal ausgetestet (im Moment zähle ich die Stringlängen), hat aber den Nachteil, dass es im Moment im Schnitt 10 MB zuviel ermittelt. Liegt wahrscheinlich daran, dass ich in der Schleife zum Erzeugen lokale Variablen habe. Der SQL-String an sich wird im Stringbuilder erzeugt. Ich werde mal abchecken, was passiert, wenn ich die lokalen Variablen eine Ebene nach oben schicke (sind dann immer noch lokal).
muffi 06.06.2014
Nur so aus neugier. Was hat dein Test ergeben? Welche Variante hat am besten funktioniert / oder auch garnicht?
Floyd 19.06.2014
Zum Bulkloader bin ich noch nicht gekommen, das muss ich noch testen. Im Moment läuft die Routine immer noch mit x=x+string.length. Die Möglichkeit mit GC.GetTotalMemory ist anscheinend ziemlich zeitintensiv und Marshal.SizeOf liefert nur die Größe des Objekts (ohne Daten).
muffi 20.06.2014

Stelle deine .net-Frage jetzt!