从php中的csv文件读取大数据[重复]
Posted
技术标签:
【中文标题】从php中的csv文件读取大数据[重复]【英文标题】:Read large data from csv file in php [duplicate] 【发布时间】:2013-07-05 09:34:42 【问题描述】:我正在读取 csv 并使用 mysql 检查记录是否存在于我的表中或不在 php 中。
csv 有近 25000 条记录,当我运行我的代码时,它在 2m 10s 后显示“服务不可用”错误(加载时间:2m 10s)
这里我添加了代码
// for set memory limit & execution time
ini_set('memory_limit', '512M');
ini_set('max_execution_time', '180');
//function to read csv file
function readCSV($csvFile)
$file_handle = fopen($csvFile, 'r');
while (!feof($file_handle) )
set_time_limit(60); // you can enable this if you have lot of data
$line_of_text[] = fgetcsv($file_handle, 1024);
fclose($file_handle);
return $line_of_text;
// Set path to CSV file
$csvFile = 'my_records.csv';
$csv = readCSV($csvFile);
for($i=1;$i<count($csv);$i++)
$user_email= $csv[$i][1];
$qry = "SELECT u.user_id, u.user_email_id FROM tbl_user as u WHERE u.user_email_id = '".$user_email."'";
$result = @mysql_query($qry) or die("Couldn't execute query:".mysql_error().''.mysql_errno());
$rec = @mysql_fetch_row($result);
if($rec)
echo "Record exist";
else
echo "Record not exist";
注意:我只想列出表中不存在的记录。
请建议我解决这个问题...
【问题讨论】:
内存限制怎么办?你检查过你的日志吗? @Robert 让我检查日志... 这里是时间日志信息:时间 - 5m 44s (onload: 5m 44s) 总内存 - 2.8 MB 增加执行时间。 哪里说服务不可用 【参考方案1】:一般情况下,500错误会出现“Service Unavailable”错误。 我认为这是因为执行时间不足。请检查您的日志/浏览器控制台,您可能会看到 500 错误。
首先, 让 set_time_limit(60) 脱离循环。
做一些改变,比如,
-
在 user_email_id 列上应用 INDEX,这样您就可以通过选择查询更快地获取行。
不要回显消息,保持输出缓冲区空闲。
和
我已经使用开源程序完成了这些拍摄。你可以在这里得到它http://sourceforge.net/projects/phpexcelreader/
试试这个。
【讨论】:
是的,我在控制台上看到了 500 - 内部服务器错误,我还添加了代码以增加最大执行时间 ini_set('memory_limit', '512M'); ini_set('max_execution_time', '180'); set_time_limit(60) 在 while 循环中,将其置于 readCSV() 之外【参考方案2】:处理大文件的绝佳方法位于:https://***.com/a/5249971/797620
此方法用于http://www.cuddlycactus.com/knownpasswords/(页面已被删除)在几毫秒内搜索超过 170+ 百万个密码。
【讨论】:
第二个链接坏了,所以我们看不到这个方法是如何使用的。因此,这使得第二段毫无意义,并且答案变得非常低质量,因为它只是一个链接答案。【参考方案3】:经过一番努力,我终于找到了一个好的解决方案,也许它也可以帮助别人。
当我尝试包含 18226 行的 2,367KB csv 文件时,不同 php 脚本花费的最少时间是
(1) 来自 php.net fgetcsv
名为 CsvImporter
的文档,以及
(2)file_get_contents => PHP Fatal error: Allowed memory exhausted
(1) 花了 0.92574405670166 (2) 取 0.12543702125549 (字符串形式) & 0.52903485298157 (拆分成数组) 注意:此计算不包括添加到mysql。
我找到的最佳解决方案是使用3.0644409656525
,包括添加到数据库和一些条件检查。
处理一个 8MB 文件需要 11 秒。
解决方案是:
$csvInfo = analyse_file($file, 5);
$lineSeperator = $csvInfo['line_ending']['value'];
$fieldSeperator = $csvInfo['delimiter']['value'];
$columns = getColumns($file);
echo '<br>========Details========<br>';
echo 'Line Sep: \t '.$lineSeperator;
echo '<br>Field Sep:\t '.$fieldSeperator;
echo '<br>Columns: ';print_r($columns);
echo '<br>========Details========<br>';
$ext = pathinfo($file, PATHINFO_EXTENSION);
$table = str_replace(' ', '_', basename($file, "." . $ext));
$rslt = table_insert($table, $columns);
if($rslt)
$query = "LOAD DATA LOCAL INFILE '".$file."' INTO TABLE $table FIELDS TERMINATED BY '$fieldSeperator' ";
var_dump(addToDb($query, false));
function addToDb($query, $getRec = true)
//echo '<br>Query : '.$query;
$con = @mysql_connect('localhost', 'root', '');
@mysql_select_db('rtest', $con);
$result = mysql_query($query, $con);
if($result)
if($getRec)
$data = array();
while ($row = mysql_fetch_assoc($result))
$data[] = $row;
return $data;
else return true;
else
var_dump(mysql_error());
return false;
function table_insert($table_name, $table_columns)
$queryString = "CREATE TABLE " . $table_name . " (";
$columns = '';
$values = '';
foreach ($table_columns as $column)
$values .= (strtolower(str_replace(' ', '_', $column))) . " VARCHAR(2048), ";
$values = substr($values, 0, strlen($values) - 2);
$queryString .= $values . ") ";
//// echo $queryString;
return addToDb($queryString, false);
function getColumns($file)
$cols = array();
if (($handle = fopen($file, 'r')) !== FALSE)
while (($row = fgetcsv($handle)) !== FALSE)
$cols = $row;
if(count($cols)>0)
break;
return $cols;
else return false;
function analyse_file($file, $capture_limit_in_kb = 10)
// capture starting memory usage
$output['peak_mem']['start'] = memory_get_peak_usage(true);
// log the limit how much of the file was sampled (in Kb)
$output['read_kb'] = $capture_limit_in_kb;
// read in file
$fh = fopen($file, 'r');
$contents = fread($fh, ($capture_limit_in_kb * 1024)); // in KB
fclose($fh);
// specify allowed field delimiters
$delimiters = array(
'comma' => ',',
'semicolon' => ';',
'tab' => "\t",
'pipe' => '|',
'colon' => ':'
);
// specify allowed line endings
$line_endings = array(
'rn' => "\r\n",
'n' => "\n",
'r' => "\r",
'nr' => "\n\r"
);
// loop and count each line ending instance
foreach ($line_endings as $key => $value)
$line_result[$key] = substr_count($contents, $value);
// sort by largest array value
asort($line_result);
// log to output array
$output['line_ending']['results'] = $line_result;
$output['line_ending']['count'] = end($line_result);
$output['line_ending']['key'] = key($line_result);
$output['line_ending']['value'] = $line_endings[$output['line_ending']['key']];
$lines = explode($output['line_ending']['value'], $contents);
// remove last line of array, as this maybe incomplete?
array_pop($lines);
// create a string from the legal lines
$complete_lines = implode(' ', $lines);
// log statistics to output array
$output['lines']['count'] = count($lines);
$output['lines']['length'] = strlen($complete_lines);
// loop and count each delimiter instance
foreach ($delimiters as $delimiter_key => $delimiter)
$delimiter_result[$delimiter_key] = substr_count($complete_lines, $delimiter);
// sort by largest array value
asort($delimiter_result);
// log statistics to output array with largest counts as the value
$output['delimiter']['results'] = $delimiter_result;
$output['delimiter']['count'] = end($delimiter_result);
$output['delimiter']['key'] = key($delimiter_result);
$output['delimiter']['value'] = $delimiters[$output['delimiter']['key']];
// capture ending memory usage
$output['peak_mem']['end'] = memory_get_peak_usage(true);
return $output;
【讨论】:
function analyse_file
取自php.net/manual/fr/function.fgetcsv.php#101238
我设法在我的定位器应用程序中使用 MySQL 加载数据方法进行 CSV 处理。 100,00 个位置在 75 秒内加载,而使用 fget_csv() 或文件分块则需要 10 小时。如果您将 CSV 直接加载到持久数据存储中,绝对值得研究。大多数 SQL 引擎都有类似的功能。谢谢拉扎!以上是关于从php中的csv文件读取大数据[重复]的主要内容,如果未能解决你的问题,请参考以下文章