我有一个包含两列的sql表:OldValue和NewValue。我在excel电子表格中有两个相同的列。我想找到迭代数据库和Excel电子表格的最快方法,检查数据库中的OldValue列是否与电子表格中的OldValue列相同。
我的逻辑工作使我遍历整个sql列(333228条记录),寻找与具有153 000行的excel列匹配。这个迭代性能很重,需要几个小时甚至没有完成 - 最终挂起。我怎样才能快速做到这一点? 153 000 x 333228 = 240亿次迭代,计算量很大。
我在这里阅读https://codereview.stackexchange.com/questions/47368/looping-through-an-excel-document-in-c但无法得到我想要的东西。该代码有效并且已经找到500个匹配,但考虑到我需要通过数据库中的333228条记录,它很慢。
List<sim_info> exel_sims = new List<sim_info>();
Microsoft.Office.Interop.Excel.Application Excel_app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbooks work_books = Excel_app.Workbooks;
string excel_file_path = Application.StartupPath + "\\TestSample";
Microsoft.Office.Interop.Excel.Workbook work_book = work_books.Open(excel_file_path);
work_book.SaveAs(excel_file_path + ".csv", Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows);
Microsoft.Office.Interop.Excel.Sheets work_sheets = work_book.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet work_sheet = (Microsoft.Office.Interop.Excel.Worksheet)work_sheets.get_Item(1);
for (int j = 2; j < work_sheet.Rows.Count; j++)
{
try
{
temp_sim_info.msisdn = cell_to_str(work_sheet.Cells[j, 1]).Trim();
temp_sim_info.mtn_new_number = cell_to_str(work_sheet.Cells[j, 8]).Trim();
temp_sim_info.status = cell_to_str(work_sheet.Cells[j, 9]).Trim();
if (temp_sim_info.msisdn.Length < 5 || temp_sim_info.mtn_new_number.Length > 15) //Valid cellphone number length contains 11 digits +27XXXXXXXXX / 14 digits for the new msisdn. This condition checks for invalid cellphone numbers
{
if (zero_count++ > 10)
break;
}
else
{
zero_count = 0;
exel_sims.Add(temp_sim_info);
if (exel_sims.Count % 10 == 0)
{
txtExcelLoading.Text = exel_sims.Count.ToString();
}
}
}
catch
{
if (zero_count++ > 10)
break;
}
// }
txtExcelLoading.Text = exel_sims.Count.ToString();
work_sheet.Columns.AutoFit();
for (int i = 0; i < TestTableInstance.Rows.Count; i++)
{
string db_oldNumbers = "";
string db_CellNumber = "";
if (!TestTableInstance.Rows[i].IsNull("OldNumber"))
db_oldNumbers = TestTableInstance[i].OldNumber;
else
db_oldNumbers = TestTableInstance[i].CellNumber;
if (!TestTableInstance.Rows[i].IsNull("CellNumber"))
db_CellNumber = temp_sim_info.mtn_new_number;
for (int k = 0; k < exel_sims.Count; k++)
{
sim_info sim_Result = exel_sims.Find(x => TestTableInstance[i].CellNumber == x.msisdn);
if (TestTableInstance[i].CellNumber == exel_sims[k].msisdn && sim_Result != null)
{
//If match found then do logic here
}
}
}
}
MessageBox.show("DONE");
TableInstance是内存中加载的数据库的DataSet。第二个内部循环迭代每个记录的整个DB列,直到它在电子表格的OldValue列的第一行中找到匹配项。
我的代码有效。 当我有一个800行的excel表和一个由1000个记录组成的数据库表时,它经过了测试和测试。它在5分钟内完成。但是对于十万条记录来说,它会挂起几个小时。
答案 0 :(得分:0)
完全!你为什么要使用C#呢?将Excel文件加载到数据库中的临时表中,并在实际的SQL表(据称具有Excel文件中的所有数据)和临时表(或视图)之间进行比较。这种比较应该在几秒钟内完成。
select *
from dbtest02.dbo.article d2
left join dbtest01.dbo.article d1 on d2.id=d1.id
左连接显示左表“dbtest02.dbo.article”中的所有行,即使“dbtest01.dbo.article”中没有匹配项:
OR
select * from dbtest02.dbo.article
except
select * from dbtest01.dbo.article
请参阅以下链接,了解有关如何执行此操作的其他一些建议。