更新两个不同表中字段的最有效方法是?

时间:2016-05-13 14:20:32

标签: mysql sql csv coldfusion sql-update

我正在开展一个项目,我必须在两个不同的表中更新字段。首先,我使用.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)中读取数据中不同位置的信息。我之前做过更新/插入,但从未有过大量的记录。现在我必须为效率找到最好的方法。如果您对此问题有任何建议,请告诉我。谢谢。

2 个答案:

答案 0 :(得分:2)

另一种解决方案。正如你所说,记录可以更高(高达30K),存储过程似乎是一个更好的选择。你可以这样做:
首先使用CSVcfftp文件上传到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

<强>更新
使用存储过程的一些好处包括:

  • 可维护性:您可以在没有的情况下更改过程中的逻辑 需要编辑app1,app2和app3电话。
  • 安全/访问控制:更容易担心谁可以调用预定义的过程,而不是控制谁可以访问哪些表或哪些表行。
  • 效果(1):如果您的应用与您的应用不在同一台服务器上 数据库,以及您正在做的事情涉及多个查询,使用 过程通过涉及单个调用来减少网络开销 数据库,而不是与查询一样多的调用。在您的情况下,使用内联查询将使数据库服务器达到30K次(对于30K记录)。
  • 性能(2):程序的查询计划通常是缓存的, 允许您一次又一次地重复使用它而无需重新准备。

Read this

答案 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注入。