DataReader ordinal-based lookups vs named lookups

☆樱花仙子☆ 提交于 2019-12-18 05:04:07

问题


Microsoft (and many developers) claim that the SqlDataReader.GetOrdinal method improves the performance of retrieving values from a DataReader versus using named lookups ie. reader["ColumnName"]. The question is what is the true performance difference if dealing with small, paged record sets? Is it worth the extra overhead of finding and referencing ordinal indexes throughout the code?


回答1:


Microsoft recommends not calling GetOrdinal within a loop.

That would include indirect calls with the string indexer.

You can use GetOrdinal at the top of your loop put the ordinals in an array and have the indexes in the array be const or have an enum for them (no GetOrdinal at all) or use GetOrdinal into individual variables with descriptive names.

Only if your sets are small would I really consider this to be premature optimization.

It's apparently a 3% penalty.




回答2:


Any difference will be more than outweighed by maintenance overhead.

If you have that much data that it makes a noticeable difference, I'd suggest you have too much data in your client code. Or this is when you consider use ordinals rather than names




回答3:


Yes and no.

If you're dealing with a massive amount of data then you'd certainly benefit from using the ordinals rather than the column names.

Otherwise, keep it simple, readable, and somewhat safer - and stick with the column names.

Optimize only when you need to.




回答4:


I created a wrapper for SqlDataReader that stores orindals in a dictionary with the column name as the key.

It gives me ordinal performance gains while keeping the code more readable and less likely to break if someone changes the column order returned from stored procedures.

Friend Class DataReader
Implements IDisposable

Private _reader As SqlDataReader
Private _oridinals As Dictionary(Of String, Integer)
Private Shared _stringComparer As StringComparer = StringComparer.OrdinalIgnoreCase 'Case in-sensitive

Public Sub New(reader As SqlDataReader)
    Me._reader = reader
    Me.SetOrdinals()
End Sub

Private Sub SetOrdinals()
    Me._oridinals = New Dictionary(Of String, Integer)(_stringComparer)
    For i As Integer = 0 To Me._reader.FieldCount - 1
        Me._oridinals.Add(Me._reader.GetName(i), i)
    Next
End Sub

Public Function Read() As Boolean
    Return Me._reader.Read()
End Function

Public Function NextResult() As Boolean
    Dim value = Me._reader.NextResult()
    If value Then
        Me.SetOrdinals()
    End If
    Return value
End Function

Default Public ReadOnly Property Item(name As String) As Object
    Get
        Return Me._reader(Me.GetOrdinal(name))
    End Get
End Property

Public Function GetOrdinal(name As String) As Integer
    Return Me._oridinals.Item(name)
End Function

Public Function GetInteger(name As String) As Integer
    Return Me._reader.GetInt32(Me.GetOrdinal(name))
End Function

Public Function GetString(ordinal As Integer) As String
    Return Me._reader.GetString(ordinal)
End Function

Public Function GetString(name As String) As String
    Return Me._reader.GetString(Me.GetOrdinal(name))
End Function

Public Function GetDate(name As String) As Date
    Return Me._reader.GetDateTime(Me.GetOrdinal(name))
End Function

Public Function GetDateNullable(name As String) As Nullable(Of Date)
    Dim o = Me._reader.GetValue(Me.GetOrdinal(name))
    If o Is System.DBNull.Value Then
        Return Nothing
    Else
        Return CDate(o)
    End If
End Function

Public Function GetDecimal(name As String) As Decimal
    Return Me._reader.GetDecimal(Me.GetOrdinal(name))
End Function

Public Function GetBoolean(name As String) As Boolean
    Return Me._reader.GetBoolean(Me.GetOrdinal(name))
End Function

Public Function GetByteArray(name As String) As Byte()
    Return CType(Me._reader.GetValue(Me.GetOrdinal(name)), Byte())
End Function

Public Function GetBooleanFromYesNo(name As String) As Boolean
    Return Me._reader.GetString(Me.GetOrdinal(name)) = "Y"
End Function

'Disposable Code

End Class


来源:https://stackoverflow.com/questions/5860519/datareader-ordinal-based-lookups-vs-named-lookups

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!