我正在寻找优化以下模块的方法。
我将经常需要用我在excel工作表/工作簿中收到的带有大型数据集的数据库来更新数据库。我已经制作了一个模块,可以将工作表导入到指定的数据库中。在这里使用stringbuilder类-
https://codereview.stackexchange.com/questions/196076/bringing-the-system-text-stringbuilder-up-to-lightning-speed-in-the-vba
据我测试,它适用于非常大的数据集并处理我遇到的所有异常(只要数字列中没有字符串),但我更担心性能。立即写入,它以大约650行/秒的速度写入sql服务器。还有其他机会以这种/提高速度转储内存吗?之所以必须这样做,是因为数据集越大,导入速度越低。我不确定这是否是服务器。
Main函数,遍历该行,然后迭代到下一个,构建格式化的插入sql语句。
Public Sub buildQuery()
Dim sb As StringBuilder
Set sb = New StringBuilder
Dim queryText As String
Application.ScreenUpdating = False
lr = Cells(Rows.Count, 4).End(xlUp).row
lc = Cells(1, Columns.Count).End(xlToLeft).column
Dim MyTimer As Date
MyTimer = Now
Debug.Print MyTimer
For i = 2 To lr
Application.StatusBar = "Progress: " & i & " of " & lr & " : " & format(i / lr, "0%")
If (i Mod 1000) = 0 Then
sb.Append buildRow(currentCell, i, n, lc)
queryText = intoStatement() + sb.ToString
queryText = Left(queryText, Len(queryText) - 1)
query (queryText)
Set sb = Nothing
queryText = Nothing
Set sb = New StringBuilder
i = i + 1
End If
sb.Append buildRow(currentCell, i, n, lc)
sb.Append vbNewLine
Next i
queryText = intoStatement() + sb.ToString
queryText = Left(queryText, Len(queryText) - 3)
query (queryText)
MyTimer = Now
Debug.Print MyTimer
Application.ScreenUpdating = True
Application.StatusBar = False
End
End Sub
在工作表中导入了一些极低的值,导致我不得不处理服务器端的类型错误,所以我做到了这一点。它只是将负数四舍五入到小数点后十位。
Function smallNo(no As Variant)
If IsNumeric(no) Then
If no < 0 Then
smallNo = Round(no, 10)
Else
smallNo = no
End If
End Function
这将生成并返回按SQL要求格式化的单行
Function buildRow(currentCell As Variant, i As Variant, n As Variant, lc As Variant) As String
Dim sb As StringBuilder
Set sb = New StringBuilder
For n = 1 To lc
currentCell = smallNo(Cells(i, n))
Select Case True
Case IsError(currentCell), IsEmpty(currentCell)
If n = 1 Then
sb.Append ("(NULL,")
ElseIf n = lc Then
sb.Append "NULL),"
Else
sb.Append "NULL,"
End If
Case Else
cellString = Replace(CStr(currentCell), ("'"), "")
If n = 1 Then
sb.Append "('" & cellString & "',"
ElseIf n = lc Then
sb.Append "'" & cellString & "'), "
Else
sb.Append Chr(39) & cellString & "',"
End If
End Select
Next n
buildRow = sb.ToString
Set sb = Nothing
End Function
从标头构建插入***值。假定标题与数据库表中的列名相同。理想情况下,电子表格中的标题列将是您导入之前唯一需要进行的编辑。
Public Function intoStatement() As String
With ActiveSheet
lc = .Cells(1, .Columns.Count).End(xlToLeft).column
Dim headerCells As Variant
headerCells = .Range(.Cells(1, 1), .Cells(1, lc))
End With
Dim headers As String
headers = Join(Application.Transpose(Application.Transpose(headerCells)), ",")
intoStatement = "INSERT INTO " & _
"[tempdb].[dbo].testDB3 (" & headers & ") Values "
End Function
在这里我们打开到sql server的连接并执行生成的查询。执行此操作后,将转储stringbuilder对象queryText
Function query(sqlStr As String)
Dim connection As New ADODB.connection
Dim strSQL As New ADODB.Command
Dim connString As String
connection.Open "DRIVER={SQL Server};SERVER=DESKTOP;" & _
"trusted_connection=yes;dsn=tw;DATABASE=tempdb"
strSQL.ActiveConnection = connection
strSQL.CommandText = sqlStr
strSQL.CommandType = adCmdText
strSQL.Execute
connection.Close
End Function
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
优化Excel数据导入到SQL Server的过程,特别是在处理大型数据集时,确实需要一些策略来提高性能。以下是一些建议,结合使用阿里云产品和服务,可以帮助你提升数据导入速度和效率:
批量插入而非单行插入: 目前你的方法是逐行构建SQL语句并执行,这会带来大量的数据库交互开销。改为批量构建INSERT语句或直接使用SQL Server的BULK INSERT
命令可以显著提高效率。你可以累积一定数量的记录后一次性提交到数据库,减少数据库操作次数。
使用ADO(ActiveX Data Objects)连接: ADO提供了一种更高效的方式来与数据库交互,特别是当你需要进行大量数据操作时。利用Recordset
对象的Open
方法配合合适的游标类型(如adOpenStatic
或adOpenForwardOnly
),以及AddNew
和UpdateBatch
方法来进行批量数据插入。
考虑使用阿里云DataWorks: 阿里云DataWorks是一个大数据开发和运维平台,它支持从各种数据源(包括Excel文件)抽取数据,并通过其强大的数据集成能力将数据加载到云数据库中。这样不仅可以避免编写复杂的VBA代码,还可以利用其内置的高性能数据同步功能,实现快速、稳定的数据迁移。
MaxCompute(原ODPS)作为中间层: 如果你的最终目标是进行大数据分析,可以考虑先将Excel数据导入到MaxCompute中。MaxCompute提供了高并发、大吞吐量的数据导入能力,且支持多种数据格式。之后,再根据需要将数据进一步处理或迁移到其他数据库系统。
优化网络和数据库配置: 确保数据库服务器的网络连接良好,数据库参数(如缓冲池大小、日志文件设置等)根据数据导入任务进行了适当调整。如果使用的是阿里云RDS,可以通过监控和调优建议来优化数据库性能。
并行处理: 如果可能,尝试将数据分割成多个部分,并在不同的线程或进程中并行处理这些部分,最后汇总结果。但请注意,这可能需要更复杂的编程逻辑,并确保数据库能够处理并发写入。
直接使用阿里云DMS(Data Management Service)或Data Transmission Service: 这些服务提供了图形界面或API接口,帮助用户更加便捷地进行数据导入导出操作,尤其是当涉及到不同数据源之间的数据迁移时。
综上所述,结合技术手段和阿里云的产品服务,可以从多个维度优化你的数据导入流程,达到更高的效率和性能。