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. SQL查詢/查找基於排名
- 2. 基於查找表重命名錶
- 3. 與命名查詢
- 4. 查詢中的DataReader
- 5. GRAILS與to_char命名查詢
- 6. NHiberante Linq與命名查詢
- 7. setCacheQuery與HibernateTemplate命名查詢
- 8. SQL查詢基於序列
- 9. nhibernate命名查詢,找不到名稱
- 10. 加入查詢VB.net DataReader的
- 11. 基於DataReader名稱的查找 - 底層實際發生了什麼,使得它們比循環中基於序數的查找慢得多?
- 12. Android:基於用戶名的sqlite查詢
- 13. 命名查詢更復雜的基於Hibernate
- 14. 查找對象的名稱與編號
- 15. Django的形式與基於查詢集
- 16. 命名Hibernate查詢的「命名查詢未知」?
- 17. jpa命名查詢未找到
- 18. java.lang.IllegalArgumentException異常:未找到命名查詢:
- 19. JBoss/Hibernate IllegalArgumentException:命名查詢未找到
- 20. JPA命名查詢
- 21. Grails命名查詢
- 22. 從命名查詢
- 23. JPA命名查詢
- 24. 命名SQL查詢
- 25. SSAS:命名查詢
- 26. 基於子查詢
- 27. 基於子查詢
- 28. 基於BEx查詢
- 29. SQL查詢列名基於where子句
- 30. ms-access爲基於查詢的逗號排序一個列?
一些基準:http://blog.maskalik.com/ado-net/data-reader-performance-optimizations/ – nawfal 2015-07-31 14:29:53