22 Stimmen

Warum die GetOrdinal() Methode des SqlDataReader verwenden

Was ist der Unterschied zwischen dem Lesen eines Werts aus einem SqlDataReader unter Verwendung dieser Syntax:

Dim reader As SqlClient.SqlDataReader
reader("value").ToString()

ODER

Dim reader As SqlClient.SqlDataReader
reader.GetString(reader.GetOrdinal("value"))

16voto

Alex Black Punkte 13274

Ich denke, der Grund, GetOrdinal() zu verwenden, liegt darin, dass Sie das Ergebnis zwischenspeichern und mehrmals zur Leistungssteigerung wieder verwenden können.

Zum Beispiel.

Dim reader As SqlClient.SqlDataReader
int valueOrdinal = reader.GetOrdinal("value");
while ( ... )
{
    var value = reader.GetString(valueOrdinal);
}

1 Stimmen

Hat jemand eine Idee über den Leistungsunterschied zwischen der Verwendung von GetOrdinal(..) innerhalb einer Schleife im Vergleich zur tatsächlichen Datenabfrage aus der Datenbank?

4 Stimmen

Ich habe einen Leistungstest für einen Web-API-Dienst, der ungefähr 30-40 Datensätze aus einer in einer Datenbank gespeicherten gespeicherten Prozedur (mit mehreren Ergebnismengen) liest und Json von etwa 8 KB Größe zurückgibt. In diesem Test habe ich alle GetOrdinal() durch statische int-Konstanten ersetzt und als Ergebnis habe ich eine Leistungssteigerung von 2% erzielt... lohnt es sich also, einen solchen Cach der Spaltennamen zu erstellen? - Ich denke, in den meisten Szenarien nicht. Das Lesen von Daten aus der Datenbank und die Datenserialization zu Json in echten Szenarien werden die Leistung stärker beeinflussen, daher denke ich, dass das Cachen von Ordnungszahlen das Letzte ist, was getan werden sollte, wenn Sie bereits alles andere optimiert haben...

0 Stimmen

Ich habe vielleicht falsch gelesen, aber ich glaube, dass bei der Verwendung von GetOrdinal auch eine Zeile analysiert wird, ohne sich auf den Index jedes Elements verlassen zu müssen, da ein Ergebnis nicht immer indiziert sein könnte, wie man es erwarten würde. Die Verwendung von GetOrdinal ermöglicht den Zugriff auf die Spaltenwerte eines Readers, ohne genau zu wissen, wo sich die Indexposition des Werts befindet.

8voto

joe Punkte 33003

GetOrdinal führt zuerst eine Groß-/Kleinschreibung-Abfrage durch. Wenn diese fehlschlägt, wird eine zweite Groß-/Kleinschreibung-unabhängige Suche durchgeführt. GetOrdinal ist breiteninsensitiv. Weil ordinalbasierte Abfragen effizienter sind als benannte Abfragen, ist es ineffizient, GetOrdinal innerhalb einer Schleife aufzurufen. Sparen Sie Zeit, indem Sie GetOrdinal einmal aufrufen und die Ergebnisse einer ganzen Zahl zuweisen, die in der Schleife verwendet werden kann.

Quelle: http://msdn.microsoft.com/de-de/library/system.data.sqlclient.sqldatareader.getordinal.aspx

8 Stimmen

Wortwörtliche Kopie von msdn.microsoft.com/en-us/library/… ;-)

4 Stimmen

Warum nicht einfach auf den gesamten Artikel verlinken? Sein Kommentar enthält viele Inhalte nicht.

8 Stimmen

Typischerweise verlinken Sie nicht einfach auf den gesamten Artikel, da er möglicherweise nicht für immer verfügbar ist und es auch viel zu durchsuchen ist. Sie zitieren den relevanten Teil und verlinken darauf.

3voto

Sergey Punkte 3124

Ich möchte nur hinzufügen, dass der Kontext, wie viele Datensätze Sie erwarten, eine große Rolle spielt, denn wenn Sie nur eine Zeile zurückgeben, wäre der Leistungsunterschied zwischen den beiden nicht signifikant. Wenn Sie jedoch über viele Zeilen iterieren, ist die Verwendung eines typisierten Zugriffs für die Leistung besser, da es optimiert ist. In diesem Fall, wenn Sie die beste Leistung erzielen möchten, indem Sie einen Spaltennamen verwenden, rufen Sie GetOrdinal einmal auf, speichern Sie es in einer Variablen und verwenden dann den typisierten Zugriff mit dem Spaltenindex in Ihrer Schleife. Dies würde die beste Leistung erzielen.

wenn Sie neugierig auf den Leistungsunterschied sind, schauen Sie sich meinen Blog-Beitrag an

0voto

ChrisG65 Punkte 61

Ihre individuelle Laufleistung kann variieren, aber...

Je mehr Zeilen Sie abrufen, desto mehr Leistungsverbesserung werden Sie feststellen. Ich verwende gerne Spaltenaliasse in meinen SELECT-Anweisungen, wie

select
    physical_column_name as "MyFieldName"

und habe eine Methode geschrieben, die selbsterklärend sein sollte,

public Dictionary GetOrdinalsByName(DbDataReader reader)

Daher sehen meine Zuweisungen so aus

public void BindRow(DbDataReader dr)
{
    TerminationDate = dr.GetDateTime(_columnOrdinals["TerminationDate"]);

Dictionaries führen in der Nähe von O(1) aus; daher ist dies ein angemessener Kompromiss zwischen Leistung und Wartbarkeit.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X