Microsoft(和許多開發人員)claim SqlDataReader.GetOrdinal方法提高了從DataReader中檢索值的性能,而不是使用命名查找的性能。讀取器[ 「的ColumnName」]。問題是如果處理小的分頁記錄集,那麼性能差異是什麼true?是否值得在代碼中查找和引用序號索引的額外開銷?DataReader基於序號的查找與命名查詢
回答
Microsoft recommends not calling GetOrdinal within a loop.
這將包括與字符串索引間接調用。
您可以在循環的頂部使用GetOrdinal,將序數放在數組中,並使數組中的索引爲常量,或者爲它們設置枚舉(根本不使用GetOrdinal),或者將GetOrdinal用於具有描述性名稱的單個變量。
只有當你的設置很小時,我纔會認爲這是過早的優化。
是和否。
如果你正在處理大量的數據,那麼你肯定會從使用序號而不是列名獲益。
否則,請保持簡單,可讀,有些安全 - 並堅持使用列名稱。
僅在需要時進行優化。
「可讀的,有些更安全 - 並堅持與列名」我要說的是,是序數提供的。你可以給你的序號一個不錯的名字'int ordinalUserName = reader.GetOrdinal(「user_name」)'所以它也是可讀的。如果你在一個地方聲明所有的序號,而不是在某個邏輯中分散列名,它也可以被認爲更可讀和更安全。 – row1 2014-03-21 05:06:13
任何差異將比維護開銷壓倒了。
如果你有這麼多的數據,它會產生明顯的差異,我建議你的客戶端代碼中有太多的數據。或者這是當你考慮使用序號而不是名稱
我創建了一個SqlDataReader的包裝,存儲orindals在列名作爲關鍵字的字典。
它使我獲得了序數性能提升,同時保持代碼更具可讀性,並且在有人更改從存儲過程返回的列順序時不太可能中斷。
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
是不是SqlDataReader已經有一個字典作爲其GetOrdinal()實現的一部分?你是否真的測量過Item [string]的任何性能改進? – binki 2013-09-17 17:24:56
- 1. 與命名查詢
- 2. 查詢中的DataReader
- 3. NHiberante Linq與命名查詢
- 4. SQL查詢基於序列
- 5. nhibernate命名查詢,找不到名稱
- 6. 加入查詢VB.net DataReader的
- 7. Android:基於用戶名的sqlite查詢
- 8. 基於DataReader名稱的查找 - 底層實際發生了什麼,使得它們比循環中基於序數的查找慢得多?
- 9. Django的形式與基於查詢集
- 10. 命名Hibernate查詢的「命名查詢未知」?
- 11. jpa命名查詢未找到
- 12. JBoss/Hibernate IllegalArgumentException:命名查詢未找到
- 13. 沒有找到命名查詢
- 14. JPA命名查詢
- 15. SSAS:命名查詢
- 16. 基於子查詢
- 17. 基於BEx查詢
- 18. ms-access爲基於查詢的逗號排序一個列?
- 19. 基於查詢排序的SQL行數?
- 20. 查找鑑於命名空間屬性
- 21. JPA命名查詢不能與Hibernate
- 22. 查詢LINQ與DDL DataTextField基於查詢LINQ和ObjectDataSource
- 23. 的Java命名查詢
- 24. 查詢基於過濾器的查詢linq查詢
- 25. 查詢基於位的值
- 26. 基於查詢的Elasticsearch upsert
- 27. 查詢 - 基於行的表
- 28. 基於ManyToManyField的Django查詢
- 29. Google App Engine:與查詢相比,基於密鑰的查找速度快多少?
- 30. 基於最大序列號查詢特定字段
一些基準:http://blog.maskalik.com/ado-net/data-reader-performance-optimizations/ – nawfal 2015-07-31 14:29:53