我是一名学生,为夏天安排工作。我被赋予了处理从excel到SQL Server数据库的数据输入的任务,用于多年来进行的调查。任务概述如下:
有三个表,主要事件,个人事件和个人。一个活动有很多个人活动,个人活动有很多个人。我的代码只关注最后两个表。
我读了两个文件,一个文件中所有单个事件的列表,另一个文件中所有个体的列表。个人的数据告诉我它与之相关的个人事件。
我的代码基本上读取单个事件,然后查看第二个文件中的任何相关个人。对于个人文件中的每一行,如果它是关联的,则将其插入到正确的表中,否则将其写入新文件。遍历整个文件后,新文件将复制到旧文件,从而删除已输入数据库的数据。
这种复制已经敲了3分钟的执行时间,只是一次又一次地重读整个个人文件。但有更好的方法吗?我的样本数据的执行时间约为47秒......理想情况下,我希望它更低。
任何建议,无论多么微不足道,都会受到赞赏。
编辑: 这是我正在使用的代码的缩减版本
<?php
//not shown:
//connect to database
//input event data
//get the id of the event
//open files
$s_handle = fopen($_FILES['surveyfile']['tmp_name'],'r');//open survey file
copy($_FILES['cocklefile']['tmp_name'],'file1.csv');//make copy of the cockle file
//read files
$s_csv = fgetcsv($s_handle,'0',',');
//read lines and print lines
// then input data via sql
while (! feof($s_handle))
{
$max_index = count($s_csv);
$s_csv[$max_index]='';
foreach($s_csv as $val)
{
if(!isset($val))
$val = '';
}
$grid_no = $s_csv[0];
$sub_loc = $s_csv[1];
/*
.define more variables
.*/
$sql = "INSERT INTO indipendant_event"
."(parent_id,grid_number,sub_location,....)"
."VALUES ("
."'{$event_id}',"
."'{$grid_no}',"
//...
.");";
if (!odbc_exec($con,$sql))
{
echo "WARNING: SQL INSERT INTO fssbur.cockle_quadrat FAILED. PHP.";
}
//get ID
$sql = "SELECT MAX(ind_event_id)"
."FROM independant_event";
$return = odbc_exec($con,$sql);
$ind_event_id = odbc_result($return, 1);
//insert individuals
$c_2 = fopen('file2.csv','w');//create file c_2 to write to
$c_1 = fopen('file1.csv','r');//open the data to read
$c_csv = fgetcsv($c_1,'0',',');//get the first line of data
while(! feof($c_1))
{
for($i=0;$i<9;$i++)//make sure theres a value in each column
{
if(!isset($c_csv[$i]))
$c_csv[$i] = '';
}
//give values meaningful names
$stat_no = $c_csv[0];
$sample_method = $c_csv[1];
//....
//check whether the current line corresponds to the current station
if (strcmp(strtolower($stat_no),strtolower($grid_no))==0)
{
$sql = "INSERT INTO fssbur2.cockle"
."(parent_id,sampling_method,shell_height,shell_width,age,weight,alive,discarded,damage)"
."VALUES("
."'{$ind_event_id}',"
."'{$sample_method}',"
//...
."'{$damage}');";
//write data if it corresponds
if (!odbc_exec($con,$sql))
{
echo "WARNING: SQL INSERT INTO fssbur.cockle FAILED. PHP.";
}
$c_csv = fgetcsv($c_1,'0',',');
}
else//no correspondance
{
fputcsv($c_2,$c_csv);//write line to the new file
$c_csv = fgetcsv($c_1,'0',',');//get new line
continue;//rinse and repeat
}
}//end while, now gone through all individuals, and filled c_2 with the unused data
fclose($c_1);//close files
fclose($c_2);
copy('file2.csv','file1.csv');//copy new file to old, removing used data
$s_csv = fgetcsv($s_handle,'0',',');
}//end while
//close file
fclose($s_handle);
?>
答案 0 :(得分:3)
我可能还没有完全理解这个过程,但为什么不将整个CSV插入到数据库表中。这似乎是浪费的工作,但它可能会得到回报。完成初始导入后,找到与事件关联的任何个体应该快得多,因为DBMS将能够使用索引来加速这些查找(与基于文件的线性遍历相比)。确切地说:您的“个人”表可能会在您的“individual_event”表中有一个外键。只要你在这个外键上创建一个索引,查找就会明显加快(简单地将这个字段声明为外键可能会导致SQL服务器自动索引它但我不能肯定地说,我不是'真的使用MSSQL)。
顺便说一下,我们谈论了多少条记录?如果我们处理1000个记录,那么期望这种类型的东西在几秒钟内运行是绝对合理的。
答案 1 :(得分:2)
您可以使用文件中的数据创建临时数据库,然后使用临时数据库/表将数据导入新表单。这可能更快,特别是如果您需要进行查找,并且需要将条目标记为已处理。