我编写了一个PHP脚本,使用this library从excel文件中读取一些数据。
然后以任意顺序将它插入到MySQL数据库中的某些表中。
这个Excel文件有200行,有50列,通常执行时间超过60秒。因为我的PHP托管不允许我在你看来使用set_time_limit(0);
如何提高我的脚本速度?
我的脚本读取每一行:
function read_row($excelFile, $r){
require_once './inc/excel_reader2.php';
$data = new Spreadsheet_Excel_Reader($excelFile, FALSE);
$col[0] = $data->val($r, 'E');
$col[1] = $data->val($r, 'F');
...
$col[49] = $data->val($r, 'BZ');
return $col;
}
我向MySQL插入数据的脚本:
$count = $user->rowcount($sheet=0);
if($final>0){
$count = $final;
}
$users = 0;
for($i = 4; $i <= $count; $i++){
$f = $user->val($i,'D');
$c = $user->val($i,'B');
$l = $user->val($i,'C');
$query = "INSERT INTO users(fullname ,ncode, location, createdtime) VALUES('$f','$c','$l', now());";
if(mysql_query($query)){
$users++;
}
$row = read_row($excelFile, $i);
$query = "INSERT INTO `payments` (`id`, `year`, `month`, `user`, `p1`, `p2`,... `p50`) VALUES"
. " (NULL, '$y', '$m', '$c', '$row[0]', '$row[1]', ..., '$row[49]');";
mysql_query($query);
}
答案 0 :(得分:2)
这里有一些事情:
使用microtime(true)
对脚本进行基准测试。了解脚本的确切位置时间非常有用。
e.g。
$read_file_time = microtime(true); //true makes function return value in seconds
$data = new Spreadsheet_Excel_Reader($excelFile, FALSE);
$col[0] = $data->val($r, 'E');
$col[1] = $data->val($r, 'F');
...
$col[49] = $data->val($r, 'BZ');
//Output this to screen, or log it, or whatever
$read_file_time = microtime(true) - $read_file_time; //end time - start time
return $col;
对数据库插入执行相同的操作。
接下来,我建议使用批量插入。
生成一个行数组并一次性插入所有行,而不是一次性使用您现在正在使用的单行。
所以你的数组看起来像
$rows = array(
array('value for col-0', 'value for col-1' ... 'col-49'), //row 1
array('value for col-0', 'value for col-1' ... 'col-49'), //row 2, etc.
);
您的查询看起来像
INSERT INTO `payments` (`id`, `year`, `month`, `user`, `p1`, `p2`,... `p50`) VALUES
(NULL, '$y', '$m', '$c', '$row[0][0]', '$row[0][1]', ..., '$row[0][49]'),
(NULL, '$y', '$m', '$c', '$row[1][0]', '$row[1][1]', ..., '$row[1][49]'),
...
(NULL, '$y', '$m', '$c', '$row[101][0]', '$row[101][1]', ..., '$row[101][49]')
根据文件的大小,您可能还需要批量执行此操作。
最后,你(正如@mellamokb指出的那样)你每个循环都打开文件。相反,你应该尝试类似的东西:
function read_row($ExcelFile, $r){
/*$col[0] = $ExcelFile->val($r, 'E');
$col[1] = $ExcelFile->val($r, 'F');*/
//Instead of the above, use a loop
$col = array();
$num_cols = $ExcelFile->colcount();
for($i = 0; $i < $num_cols; $i++) {
$col[] = $ExcelFile->val($r, $i);
}
//Or you can use column names if you really want
//Pass the `$col_names` as a function parameter tho
$col_names = array('E', 'F', 'BZ');
$num_cols = count($col_names);
for($i = 0; $i < $num_cols; $i++) {
$col[] = $ExcelFile->val($r, $col_names[$i]);
}
return $col;
}
require_once './inc/excel_reader2.php';
$DataFile = new Spreadsheet_Excel_Reader('path to your file', FALSE);
for($i = 4; $i <= $count; $i++) {
$row = read_row($DataFile, $i);
}
因此,要结合我的上述建议,您可以执行以下操作:
//@param $ExcelFile : excel reader2 file object
//@param $start_row : Row to start reading from, 0 based
//@param $num_rows : Number of rows to read
function read_n_rows($ExcelFile, $start_row, $num_rows) {
$rows = array();
for($i = $start_row; $i < $num_rows; $i++) {
$rows[] = read_row($ExcelFile, $i)
}
return $rows;
}