MySqlBulkLoader from DataTable - VB.net



我想从XML文件导入大约9.000.000的行为MySQL Server。目前,我正在按行插入数据行,这非常慢。我可以上传约50行/秒,这意味着要完成几天的时间。对于另一个项目,我一次将类似的数据加载到数据表中,一次将5000行加载到数据表中,然后我一次批量插入所有5000行。这使我达到了约7.500行/秒。问题在于SQL Server,这是MySQL。我从数据表中使用MySQLBulkLoader类都找不到任何人。这是可能的,我该怎么做?

XML文件中的第一个750 Elemets的示例:http://view.qrdetector.dk/test.xml

这些是我从XML文件中数据库中需要的列。

    'Create datatable to hold the information from the XML file
    Dim ReadXML_DT As New DataTable
    ReadXML_DT.Columns.Add("KoeretoejIdent", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejArtNavn", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejAnvendelseNavn", GetType(String))
    ReadXML_DT.Columns.Add("RegistreringNummerNummer", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejOplysningStatus", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejOplysningFoersteRegistreringDato", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejOplysningStelNummer", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejMaerkeTypeNavn", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejModelTypeNavn", GetType(String))
    ReadXML_DT.Columns.Add("KoeretoejVariantTypeNavn", GetType(String))
    ReadXML_DT.Columns.Add("DrivkraftTypeNavn", GetType(String))
    ReadXML_DT.Columns.Add("SynResultatSynsType", GetType(String))
    ReadXML_DT.Columns.Add("SynResultatSynsDato", GetType(String))
    ReadXML_DT.Columns.Add("SynResultatSynStatusDato", GetType(String))
    ReadXML_DT.Columns.Add("SidsteSynTjek", GetType(String))

我已经手动制作了用130.000行的CSV文件,我需要15个colums。然后,我从Plutonix的答复中使用了批量插入代码。现在,我能够在大约215秒内解析130.000行,这使我平均速度约为600行/秒。这与以前几乎相同。这是因为我与MySQL Server的连接吗?

Dim sw As Stopwatch = New Stopwatch
sw.Start()
' Finally, BulkLoad
Dim cols As String() = {"KoeretoejIdent", "KoeretoejArtNavn", "KoeretoejAnvendelseNavn", "RegistreringNummerNummer", "KoeretoejOplysningStatus", "KoeretoejOplysningFoersteRegistreringDato", "KoeretoejOplysningStelNummer", "KoeretoejMaerkeTypeNavn", "KoeretoejModelTypeNavn", "KoeretoejVariantTypeNavn", "DrivkraftTypeNavn", "SynResultatSynsType", "SynResultatSynsDato", "SynResultatSynStatusDato", "SidsteSynTjek"}
Dim rows As Integer = 0
Using dbcon As New MySqlConnection(connectionString)
    Dim bulk = New MySqlBulkLoader(dbcon)
    bulk.TableName = "synsbasen_testLoad"
    bulk.FieldTerminator = "^"
    bulk.LineTerminator = "rn"    ' == CR/LF
    bulk.FileName = "C:/Users/Synsbasen/Desktop/abc.csv"         ' full file path name to CSV 
    bulk.NumberOfLinesToSkip = 1    ' has a header (default)
    bulk.Columns.Clear()
    For Each s In cols
        bulk.Columns.Add(s)         ' specify col order in file
    Next
    rows = bulk.Load()
End Using
sw.Stop()
' SW is a stopwatch
MsgBox(rows & "rows converted and loaded in " & sw.Elapsed.TotalSeconds & " secs")

这将从XML中读取一百万行,提取数据子集,导出到CSV(使用CSVHelper),然后在大约30秒内使用MySqlBulkLoader加载它们。<</

' IEnumerable of the data parts to import
Dim recList As IEnumerable(Of SmSample)
' load some columns as a class
Using fs As FileStream = File.OpenRead(XMLFile)
    Dim xDoc = XDocument.Load(fs)
    ' its IEnumerable - leave it that way
    recList = xDoc.Descendants("Sample").
               Select(Function(j) New SmSample With {.Name = j.Element("Name").Value,
                                 .Descr = j.Element("Descr").Value,
                                 .Price = Decimal.Parse(j.Element("Price").Value),
                                 .ItemDate = DateTime.Parse(j.Element("ItemDate").Value)
                                                    }
                      )
End Using
' Have CSVHelper write them out
' this is the most time consuming part what with Disk IO and all
Using strW As New StreamWriter(CSVFile)
    Using csv As New CsvWriter(strW)
        ' ToDo: add other things like Field separators etc
        csv.Configuration.RegisterClassMap(Of SmSample.CSVItemMap)()
        csv.WriteRecords(recList)
    End Using
End Using
' Finally, BulkLoad
Dim cols As String() = {"Name", "Descr", "Price", "ItemDate"}
Dim rows As Int32 = 0
Using dbcon As New MySqlConnection(MySQLConnStr)
    Dim bulk = New MySqlBulkLoader(dbcon)
    bulk.TableName = "Sample"
    bulk.FieldTerminator = ","
    bulk.LineTerminator = "rn"    ' == CR/LF
    bulk.FileName = CSVFile         ' full file path name to CSV 
    bulk.NumberOfLinesToSkip = 1    ' has a header (default)
    bulk.Columns.Clear()
    For Each s In cols
        bulk.Columns.Add(s)         ' specify col order in file
    Next
    rows = bulk.Load()
End Using
' SW is a stopwatch
Console.WriteLine("{0} rows converted and loaded in {1} secs", 
                          rows, sw.ElapsedMilliseconds / 1000)

您的自然需要更长的时间,但是1,000,000行已经很大,因此它应该足够适当地扩展。如果您想在批处理中加载它们,则使用500k之类的东西。使用Skip()Take()

临时步骤花了9秒钟从XML中选择零件,15秒才能编写CSV,7秒为MySQL加载数据。

XML文件的细节是一个谜(发布后,该链接已添加到问题中)。由于您可以将其加载到DataTable,因此测试仅使用myDT.WriteXml(...)的结果,因此您可能必须更改该部分。将其作为LINQ查询,让CSVHelper消耗它,因为Applet本身根本不需要收集数据。

唯一的"技巧"是要格式化DateTime字段,以便MySQL可以解析:

Public Class CSVItemMap
    Inherits CsvClassMap(Of SmSample)
    Public Sub New()
        AutoMap()
        Map(Function(m) m.ItemDate).TypeConverterOption("yyyy-MM-dd")
    End Sub
End Class

csvhelper非常酷,非常强大且对结果不可或缺。

SmSample只是一个属性的类,其属性是来自较大XML数据所需的列。它的角色是a)放出您不需要/想要尽快/想要的无关列,b)为csvhelper提供的数据提供"持有人"。

答案还使用了内置的MySqlBulkLoader工具,我发现它比SQL LOAD DATA LOCAL INFILE表格更容易使用。

相关内容

  • 没有找到相关文章

最新更新