我想从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
表格更容易使用。