22 Stimmen

Warum sollte man 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 für die Verwendung von GetOrdinal() ist, dass Sie das Ergebnis zwischenspeichern und mehrmals für die Leistung wiederverwenden können.

Zum Beispiel:

Dim reader As SqlClient.SqlDataReader
Dim valueOrdinal As Integer = reader.GetOrdinal("value")
While ( ... )
{
    Dim value = reader.GetString(valueOrdinal)
}

1 Stimmen

Hat jemand eine Vorstellung davon, wie sich die Leistungsauswirkungen der Verwendung von GetOrdinal(..) innerhalb einer Zeilenschleife im Vergleich zum tatsächlichen Abrufen von Daten aus der Datenbank zum Beispiel darstellen?

4 Stimmen

Ich habe einen Leistungstest für einen Web-API-Dienst, der etwa 30-40 Datensätze aus einer in einer DB gespeicherten Prozedur (mit mehreren Resultsets) liest und Json von ca. 8 KB Größe zurückgibt. In diesem Test habe ich alle GetOrdinal() durch statische int-Konstanten ersetzt und als Ergebnis eine Leistungssteigerung von 2% erhalten... lohnt es sich also, einen solchen Zwischenspeicher für Spaltennamen zu erstellen? - Ich vermute, in den meisten Szenarien nicht. Das Lesen von Daten aus der Datenbank und die Serialisierung von Daten zu Json in realen Szenarien werden die Leistung eher beeinflussen, daher denke ich, dass das Zwischenspeichern von Ordnungen das Letzte sein sollte, was Sie tun, wenn Sie bereits alles andere optimiert haben...

0 Stimmen

Ich habe vielleicht falsch gelesen, aber ich glaube, dass das Verwenden von GetOrdinal auch eine Zeile analysiert, ohne auf den Index jedes Elements angewiesen zu sein, da ein Ergebnis nicht immer so indiziert sein kann, wie man es erwarten würde. Durch die Verwendung von GetOrdinal kann auf die Spaltenwerte eines Readers zugegriffen werden, ohne genau zu wissen, wo sich die Indexposition des Werts befindet.

8voto

joe Punkte 33003

GetOrdinal führt zuerst eine case-sensitives Suche durch. Falls dies fehlschlägt, wird eine zweite case-insensitive Suche durchgeführt. GetOrdinal ist breiten-insensitiv. Da ordinalbasierte Suchvorgänge effizienter sind als benannte Suchvorgänge, ist es ineffizient, GetOrdinal innerhalb einer Schleife aufzurufen. Sparen Sie Zeit, indem Sie GetOrdinal einmal aufrufen und das Ergebnis einer Integer-Variablen zuweisen, die innerhalb der Schleife verwendet wird.

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

8 Stimmen

Wort für Wort kopiert von msdn.microsoft.com/en-us/library/… ;-)

4 Stimmen

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

8 Stimmen

Normalerweise verlinken Sie nicht einfach auf den ganzen Artikel, weil er möglicherweise nicht für immer verfügbar ist und auch viel zu durchforsten 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 einzelne 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 sie 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 ihn in einer Variablen und verwenden Sie dann den typisierten Zugriff mit der Spaltenordinalzahl in Ihrer Schleife. Dies würde die beste Leistung erbringen.

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

0voto

ChrisG65 Punkte 61

Die Ergebnisse können variieren, aber...

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

select
    physical_column_name as "MeinFeldName"

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

public Dictionary GetOrdinalsByName(DbDataReader reader)

Also sehen dann 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 vernünftiger 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