我正在开展一个项目,我必须在两个不同的表中更新字段。首先,我使用.csv文件读取某些字段的值,然后检查if语句中的值,然后执行更新。之前在旧代码中很简单,因为我只有一个表和一个字段要更新,现在我有两个不同的表和两个字段。要做更新很容易,但我有超过15000条记录。我想知道最有效的方法是什么?如果我放两个单独的查询并运行两次更新,将运行近3万条记录。有没有办法立刻这样做?如果不是,那么运行这些更新的最佳方法是什么?这是我用来在ColdFusion服务器上运行更新的代码:
<cfset updateFile = "C:\MyFiles\Records.csv">
<cffile action="read" file="#updateFile#" variable="recordsFile">
<cfset myarray = ListToArray(recordsFile, chr(13))>
<cfset cnt = ArrayLen(myarray)>
<cfloop index="i" from="1" to=#(cnt)# step="1">
<cfif len(trim(myarray[i])) GT 0>
<cfset myrow = #replace(myarray[i],chr(10),'')#>
<cfset myrow = ListToArray(myrow,",",true)>
<cfif #myrow[23]# EQ '1'>
<cfset #myrow[23]# = 'A'>
</cfif>
<cfif #myrow[23]# EQ '2'>
<cfset #myrow[23]# = 'B'>
</cfif>
<cfif #myrow[23]# EQ '3'>
<cfset #myrow[23]# = 'D'>
</cfif>
<cfquery name="UpdateRecords" datasource="test">
Update Users
Set FiledCode = '#myrow[23]#'
Where User_Number = #myrow[1]#
</cfquery>
<cfoutput>#myrow[1]#</cfoutput><br>
</cfif>
</cfloop>
上面你可以看到我的旧代码看起来如何,现在我将不得不在该表中添加一个表和更新字段,但仍然从同一文件(Records.csv)中读取数据中不同位置的信息。我之前做过更新/插入,但从未有过大量的记录。现在我必须为效率找到最好的方法。如果您对此问题有任何建议,请告诉我。谢谢。
答案 0 :(得分:2)
另一种解决方案。正如你所说,记录可以更高(高达30K),存储过程似乎是一个更好的选择。你可以这样做:
首先使用CSV
将cfftp
文件上传到MySQL服务器上的某个位置(如果CF和MySQL位于不同的位置)。
如果MySQL与CF在同一位置,您可以跳过上述步骤。
创建一个存储过程,用于更新所需的表,其中包含所需的逻辑。
一个粗略的想法如下:
创建一个临时表,例如temp_update_table
,其中包含您需要的列。像这样:
CREATE TEMPORARY TABLE temp_update_table (meta_key, meta_value)
现在使用LOAD DATA INFILE
将csv数据插入临时表,如下所示:
LOAD DATA INFILE 'your_csv_pathname'
INTO TABLE temp_update_table FIELDS TERMINATED BY ';' (meta_key, meta_value);
然后像这样更新所需的表:
UPDATE "table"
INNER JOIN temp_update_table on temp_update_table.meta_key = "table".meta_key
SET "table".meta_value = temp_update_table.meta_value;
DROP TEMPORARY TABLE temp_update_table;
CSV上传完成后,使用cfstoredproc
标记调用上述存储过程。它会更有效率。 Reference
<强>更新强>
使用存储过程的一些好处包括:
答案 1 :(得分:0)
最重要的是确保在表格上正确设置了索引,但在此之后仍然可以提高效率。
在这种情况下,最大的收获可能来自减少对数据库的调用次数,即:减少cfquery标记的数量。例如,您可以将两个表的更新语句放在同一个查询标记中。
write preference with key <a key> value <a value>
如果您想要变得更复杂,可以将该循环分解为块并将其置于 <cfquery name="UpdateRecords" datasource="test">
Update Users
Set FiledCode = <cfqueryparam cfsqltype="cf_sql_varchar" value='#myrow[23]#'>
Where User_Number = <cfqueryparam cfsqltype="cf_sql_integer" value='#myrow[1]#'>
Update Table2
Set something = <cfqueryparam cfsqltype="cf_sql_varchar" value='#myrow[23]#'>
Where User_Number = <cfqueryparam cfsqltype="cf_sql_integer" value='#myrow[1]#'>
</cfquery>
标记内,以便它包含100个左右的更新语句。
出于效率和安全原因,您应该进行的另一项改进是使用cfquery
。这将允许您的数据库引擎缓存查询计划,然后在随后的数万次调用中重用,并保护您免受sql注入。