如何提高使用MySQL的PHP脚本的速度?
我写了一个PHP脚本,使用这个库从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); }
这里有几件事情:
使用microtime(true)
来衡量您的脚本。 对你来说知道脚本的确切位置是最有用的。
例如
$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;
为你的数据库插入做同样的事情。
接下来,我会build议使用批量插入。
生成一个行数组,并立即插入所有行,而不是您现在正在使用的时间方法中的单行。
所以你的数组看起来像
$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); }
因此,要纳入我的上述build议,你可以做一些事情:
//@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; }