【发布时间】:2014-07-11 09:17:50
【问题描述】:
我有一个包含 1500 个人的实验结果的大型数据库。每个人有 96 个数据点。我编写了以下脚本来总结并格式化数据,以便分析软件可以使用它。起初一切都很好,直到我有超过 500 个人。现在我的内存不足了。
我想知道现在是否有人建议在不牺牲速度的情况下克服内存限制问题。
这就是表格在数据库中的样子
fishId assayId allele1 allele2
14_1_1 1 个 A T
14_1_1 2 A A
$mysql = new PDO('mysql:host=localhost; dbname=aquatech_DB', $db_user, $db_pass);
$query = $mysql->prepare("SELECT genotyped.fishid, genotyped.assayid, genotyped.allele1, genotyped.allele2, fishId.sex, " .
"fishId.role FROM `fishId` INNER JOIN genotyped ON genotyped.fishid=fishId.catId WHERE fishId.projectid=:project");
$query->bindParam(':project', $project, PDO::PARAM_INT);
$query->execute();
所以这是对数据库的调用。它正在连接来自两个表的信息来构建我需要的文件。
if(!$query){
$error = $query->errorInfo();
print_r($error);
} else {
$data = array();
$rows = array();
if($results = $query->fetchAll()){
foreach($results as $row)
{
$rows[] = $row[0];
$role[$row[0]] = $row[5];
$data[$row[0]][$row[1]]['alelleY'] = $row[2];
$data[$row[0]][$row[1]]['alelleX'] = $row[3];
}
$rows = array_unique($rows);
foreach($rows as $ids)
{
$col2 = $role[$ids];
$alelleX = $alelleY = $content = "";
foreach($snp as $loci)
{
$alelleY = convertAllele($data[$ids][$loci]['alelleY']);
$alelleX = convertAllele($data[$ids][$loci]['alelleX']);
$content .= "$alelleY\t$alelleX\t";
}
$body .= "$ids\t$col2\t" . substr($content, 0, -1) . "\n";
这会解析数据。在我需要的文件中,我必须每个人有一行而不是每个人 96 行,这就是必须格式化数据的原因。在脚本的最后,我只是将 $body 写入文件。
我需要输出文件是
FishId 检测 1 检测 2
14_1_1 A T A A
$location = "results/" . "$filename" . "_result.txt";
$fh = fopen("$location", 'w') or die ("Could not create destination file");
if(fwrite($fh, $body))
【问题讨论】:
-
不要使用
$results = $query->fetchAll()){,而是一次获取和处理一行,因此您可以减少内存中 $results 的大小 -
我发现,当您不使用 EVERY 操作写入文件时,可以获得最佳性能。根据数据的长度,我经常每 100-1000 行执行一次写操作。在您的情况下,如果内存紧张或行很长,那么每次写入操作可能读取 100 条记录? (与正常读取数据相比,触摸文件相当冗长)。
-
谢谢,马克。我会试试的。
-
@anotherlife 。 . .您也许可以在数据库中做更多的工作。您应该使用输入数据和所需的输出来编辑您的问题。
-
嗨 Fluffeh,我想你的意思是在 mysql 调用中使用 LIMIT,对吗?所以我可以用 SELECT COUNT 检查有多少行,然后每 500 行执行一次写操作?
标签: php mysql performance memory pdo