我在这里阅读了许多与此类似的文章和问题,但是他们发现了一些非常接近的文章。
我在10列excel文件中有40,000行。 这里的数据是手工打印的。
有两个主要数字,MO&订单,在我需要先检查的文件中。 由于这些是手动打字,所以可能是错误的。
我有2张桌子 MO表
moID MO Order
3409 87234 23845
3410 84562 21342
etc... (38k rows)
和
printID moID user date printer
5 3409 Brad 01/24 printer1
34 3409 Brad 01/30 printer1
40 3410 Joe 01/31 printer1
etc... (9k ish and growing)
PROCESS:
我遍历c#app中的每一行,查询以获取moID。然后查询作业是否已存在,然后执行插入操作。如果无法找到moID,我会查询记录可能的MO&订单组合让他们以后修复文件。
LINK QUERYS:
curMOID = dbReports.MoNumbers.Where(r => r.moNumber == moNum && r.moOrder == orderNum).Select(c => c.id_moNumber).FirstOrDefault();
var printJobs = dbReports.PaperPrints.Where(q => q.id_moNumber == curMOID && q.printDate == printDate && q.rowExcelFile == curRow);
if (printJobs.Where(q => q.printSize == null).Count() == 0)
问题:
我的moID查询需要〜250ms(应用程序时间,直接查询为〜.075ms)。与已存在和选项列表相同。因此,每行大约需要0.5秒才能完成。 40k行需要5个多小时。我必须每天与用户这样做。有没有更好的方法来执行此操作或某种方式来加快查询通过应用程序。
答案 0 :(得分:2)
是的,这是一种痛苦的,非常痛苦的方法。有一种无痛的方式,速度更快,不涉及任何编码。
第1步:将文件导出为CSV
第2步:使用LOAD DATA INFILE
使用它将数据加载到虚拟表
LOAD DATA INFILE语句将文本文件中的行读取到 桌子的速度非常快
第3步:创建目标表
使其与虚拟表完全相同,但请确保您不希望重复的列具有唯一索引。
您可以使用CREATE TABLE LIKE声明
执行此操作 第4步:从temp中选择最终
是的,语法是
INSERT IGNORE INTO destination SELECT * FROM tmp_table
第5步:使用multi table delete清理tmp_table
您有一个表格,其中包含无法导入的行。你用一行代码
在一分钟内完成了它答案 1 :(得分:0)
除非我误以为您使用moID
作为确定是否应插入的唯一键,所以:
您最好的选择是开始批量查询。
取5000 moID
并先查询它们,然后从你留出的5000中删除任何返回,然后大量插入剩下的内容。冲洗并重复。
答案 2 :(得分:0)
谢谢@ e4c5。找到我需要去的地方。想要清楚地了解我的所作所为。过去需要5个小时,现在需要5秒。我仍在使用C#程序检查文件,csv创建并通过LOAD DATA INFILE发送。
1)创建一个CSV,每行包含所有表格中的信息。
2)创建了我想要插入
的表格的副本3)在我的案例中添加了MO和Order值的列。
4)将舞台上的moID字段更改为默认值0
5)使用LOAD DATA INFILE查询
我截断(清除)表格,所以我不必每次都创建它。只需重复使用。
"TRUNCATE TABLE `" + table + "`; " +
string.Format("LOAD DATA LOCAL INFILE '{0}' INTO TABLE `" + table + "` ", csvFullName).Replace(@"\", @"\\") +
"FIELDS TERMINATED BY ',' " +
"ENCLOSED BY '\"' " +
"LINES TERMINATED BY '\\r\\n' " +
"ignore 1 lines " +
"(@printFix, moClient, moNumber, moOrder, printComment, printPrinter, printStatus, printUser, printIssue, printSolution, printQty, rowExcelFile, excelFile) " +
"SET printDate = STR_TO_DATE(@printFix, '%m/%d/%Y'); " +
"Call PaperPrintProcedure('" + printFileName + "')";
SET printDate是一种将我的日期字符串转换为mySQL理解的字符串的方法
6)创建一个存储过程(可以运行命令)。我做了一个更新查询,根据我想要的表检查我的值。
update StagePrint test inner join MoNumbers mo on test.moNumber = mo.moNumber && test.moOrder = mo.moOrder
set test.id_moNumber = mo.id_moNumber;
7)我将暂存的行插入到我的实际表格中,只要它现在具有MO的ID。
我删除了与我的文件相同的行,因为excel文件中没有好的ID,因此现在可以使用。
DELETE FROM `PaperPrint` WHERE `excelFile` = printFileName;
insert into PaperPrint(id_moNumber, printQty, printDate, printSize, printUser, printPrinter, printStatus, printIssue, printSolution, printComment, rowExcelFile, excelFile)
select id_moNumber, printQty, printDate, printSize, printUser, printPrinter, printStatus, printIssue, printSolution, printComment, rowExcelFile, excelFile from StagePrint
where StagePrint.id_moNumber <> 0;
8)在StagedTable中查询您ID = 0
的所有记录,并修复或删除它们。