현재 Access 데이터베이스를 XML 파일로 변환하는 중입니다. 이전에이 작업을 수행했지만 이전 프로젝트의 코드가 남아 있습니다. 그러나이 코드를 사용하면 XML을 구조화 할 수 없으므로 이번에는이 작업을 수행해야합니다. 나는 XDocument
을 for
-loops와 함께 사용하고 있는데,이를 달성하기 위해 1000 행의 데이터를 두 번 처리하면 엄청 느려집니다.왜이 코드가 느려 집니까?
XDocument의 작동 방식을 읽어 보면 XElement.Add
은 실제로 전체 XML 코드를 복사하고 모든 요소를 다시 파일에 붙여 넣을 때 새 요소를 추가한다는 것을 알 수 있습니다. 이것이 사실이라면 문제가있는 곳일 것입니다.
이것은 Access에서 Xml로 데이터를 읽고 쓰는 부분으로, 저장하고 저장하는 방법이 있는지 살펴 봅니다. 데이터베이스를 27 개의 열과 12 개의 256 개의 행으로 변환하는 데는 약 30 분이 걸리지 만 작은 500 개의 행으로 구성된 작은 데이터베이스는 약 5 초가 걸립니다.
private void ReadWrite(string file)
{
using (_Connection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source={0}", pathAccess)))
{
_Connection.Open();
//Gives me values from the AccessDB: tableName, columnName, colCount, rowCount and listOfTimeStamps.
GetValues(pathAccess);
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "true"), new XElement(tableName));
for (int rowInt = 0; rowInt < rowCount; rowInt++)
{
XElement item = new XElement("Item", new XAttribute("Time", listOfTimestamps[rowInt].ToString().Replace(" ", "_")));
doc.Root.Add(item);
//colCount"-1" prevents the timestamp from beeing written again.
for (int colInt = 0; colInt < colCount - 1; colInt++)
{
using (OleDbCommand cmnd = new OleDbCommand(string.Format("SELECT {0} FROM {1} Where TimeStamp = #{2}#", columnName[colInt] , tableName, listOfTimestamps[rowInt]), _Connection))
{
XElement value = new XElement(columnName[colInt], cmnd.ExecuteScalar().ToString());
item.Add(value);
}
}
//Updates progressbar
backgroundWorker1.ReportProgress(rowInt);
}
backgroundWorker1.ReportProgress(0);
doc.Save(file);
}
}
이것은 이전 변환기의 코드입니다. 이 코드는 데이터베이스 크기에 거의 영향을받지 않으며 12556 데이터베이스는 변환하는 데 단지 1 초 밖에 걸리지 않습니다. 이 두 가지를 병합하는 방법이있을 수 있습니까?
public void ReadWrite2(string file)
{
DataSet dataSet = new DataSet();
using (_Connection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source={0}", file)))
{
_Connection.Open();
DataTable schemaTable = _Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow dataTableRow in schemaTable.Rows)
{
string tableName = dataTableRow["Table_Name"].ToString();
DataTable dataTable = dataSet.Tables.Add(tableName);
using (OleDbCommand readRows = new OleDbCommand("SELECT * from " + tableName, _Connection))
{
OleDbDataAdapter adapter = new OleDbDataAdapter(readRows);
adapter.Fill(dataTable);
}
}
}
dataSet.WriteXml(file.Replace(".mdb", ".xml"));
}
편집 :이 실행됩니다으로 그냥 명확히하기 위해, 응용 프로그램 속도가 느려집니다. 첫 번째 500 에서처럼 데이터베이스가 아무리 큰지 상관없이 5 초가 걸립니다.
UPDATE : 좋아 내가 지금 다시 주말 이후에 왔어요 내가 읽기와 하나 개의 루프에서 값을 가변 배열을 작성하고 그들을 작성하여 쓰기를 분리해서하는 코드에서 작은 조정을했다 다른. 이것은 나의 이론이 잘못되었다는 것을 증명했으며, 사실 많은 시간을 필요로하는 독서입니다. 루프 내부에서 데이터베이스를 치지 않고 값으로 배열을 채우는 방법에 대한 아이디어가 있습니까?
업데이트 2 : 이것은 DataReader.Read()
-loop으로 전환하고 모든 데이터를 즉시 수집 한 결과입니다.
public void ReadWrite3(string Save, string Load)
{
using (_Connection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source={0}", Load)))
{
_Connection.Open();
GetValues(_Connection);
_Command = new OleDbCommand(String.Format("SELECT {0} FROM {1}", strColumns, tables), _Connection);
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "true"), new XElement("plmslog", new XAttribute("machineid", root)));
using (_DataReader = _Command.ExecuteReader())
{
for (int rowInt = 0; _DataReader.Read(); rowInt++)
{
for (int logInt = 0; logInt < colCount; logInt++)
{
XElement log = new XElement("log");
doc.Root.Add(log);
elementValues = updateElementValues(rowInt, logInt);
for (int valInt = 0; valInt < elements.Length; valInt++)
{
XElement value = new XElement(elements[valInt], elementValues[valInt]);
log.Add(value);
}
}
}
}
doc.Save(Save);
}
}
병목 현상이 어디 있는지 코드를 프로파일 링 해 보셨습니까? – ChrisBint
@ChrisBint 아니요. 제 3 자 툴이나 소프트웨어없이 그렇게 할 수 있을까요? –