PHP查询运行速度慢,在非常大的MySQL数据库中会截断值


PHP query runs slow and cuts off values in very large MySQL database

我正在处理一个包含大约30个表和1000万个唯一条目的数据库。

我正在尝试使用PHP,使用echo"函数"以某种格式显示数据,并使用{$variable}放置变量。

此外,数据是分层的,所以我使用了一个join命令来包括几列,得到的表可能大约有15列。

我在Google Chrome中运行了php文件,它在一台相当不错的core2duo机器上运行了大约1个小时。

但结果集停留在大约18000个条目——顺便说一句,我对查询没有限制。

我问题中最重要的部分是如何运行此文件以获得所有结果?我不想坐在那里一遍又一遍地设置偏移量,如果有其他方法,我将不胜感激。

其次——我知道你可能需要更多信息,只是不确定是什么——我能让这个过程更快吗?我打算在一台更好的机器上重新运行它,但还有其他方法吗?

感谢

更新:

<?php
    include ('includes/functions.php');
    $connection=connectdb();
    $result=runquery('
    SELECT taxonomic_rank.rank as shortrank, scientific_name_element.name_element as shortname, sne.name_element as pname, tr.rank as prank
    FROM taxon_name_element
    LEFT JOIN scientific_name_element ON taxon_name_element.scientific_name_element_id = scientific_name_element.id
    LEFT JOIN taxon ON taxon_name_element.taxon_id = taxon.id
    LEFT JOIN taxonomic_rank ON taxonomic_rank.id = taxon.taxonomic_rank_id
    LEFT JOIN taxon_name_element AS tne ON taxon_name_element.parent_id = tne.taxon_id
    LEFT JOIN scientific_name_element AS sne ON sne.id = tne.scientific_name_element_id
    LEFT JOIN taxon AS tax ON tax.id = tne.taxon_id
    LEFT JOIN taxonomic_rank AS tr ON tr.id = tax.taxonomic_rank_id');
set_time_limit(0);
ini_set('max_execution_time',0);
    while($taxon_name_element = mysql_fetch_array($result)){
        if ($taxon_name_element['shortrank'] == 'species'){
            $subitem = $taxon_name_element['pname']."_".$taxon_name_element['shortname'];}
        else{$subitem = $taxon_name_element['shortrank']."_".$taxon_name_element['shortname'];}
        $parentitem = $taxon_name_element['prank']."_".$taxon_name_element['pname'];
        echo 
"'n<!-- http://invertnet.ill/med#{$subitem}'" -->'n
<owl:Class rdf:about='"http://invertnet.ill/med#{$subitem}'">
    <rdfs:label xml:lang='"en'">{$subitem}</rdfs:label>
    <rdfs:subClassOf rdf:resource='"http://invertnet.ill/med#{$parentitem}'"/>
</owl:Class>'n'n";}
echo "<br>".count($taxon_name_element)." number of stuff";
?>

阅读以下几行,似乎不是查询速度慢的问题。

"我在谷歌浏览器中运行了php文件,它在一台相当不错的core2duo机器上运行了大约1个小时。但结果集停止在大约18000个条目——顺便说一句,我对查询没有限制"

浏览器并不是投掷1000万条记录的最佳媒介,至少Chrome不是:-)。我的建议是在PHP文件中添加一些分页,这样就不必每次都手动设置偏移量。放一个简单的上一个下一个链接,显示每页10000条记录。

如果不是绝对需要在浏览器中运行,另一种方法可以是将所有输出写入文本文件。

查询中也有一些注意事项:为每个表添加两次LEFT JOIN的具体原因是什么?这似乎与taxoname_element.parent_id有关,但由于我不确定需求和表模式,无法对此发表评论。但如果查询运行太慢,请考虑优化它。

编辑1-我试着对您的查询进行了一些锻炼。由于您需要元素的名称和它的父名称,我认为可以在一个更简单的查询中完成,而无需两次联接相同的表。不过,它需要编码一些额外的逻辑。

我从查询中学到的一些观察结果:

  1. 元素及其父名称都来自同一个表taxon_name_element
  2. 还有另一列"rank",它也来自元素及其父元素的同一个表taxonomic_rank
  3. 从这个特定的联接taxon_name_element.parent_id = tne.taxon_id中,我了解到元素及其父元素都在同一个表"taxoname_element"中

现在让我们看看更简单的查询:

SELECT `tr`.`rank` AS `shortrank`, `sne`.`name_element` AS `shortname`, `tne`.`parent_id`, `tne`.`taxon_id`
FROM `taxon_name_element` `tne`
LEFT JOIN `scientific_name_element` `sne` ON `tne`.`scientific_name_element_id` = `sne`.`id`
LEFT JOIN `taxon` `tax` ON `tne`.`taxon_id` = `tax`.`id`
LEFT JOIN `taxonomic_rank` `tr` ON `tr`.`id` = `tax`.`taxonomic_rank_id`;

结果集现在将同时包含taxon_id和parent_id。因此,我们的想法是将所有结果存储在数组中,从而将KEY设置为parent_id。类似:

$arrOutput = $arrParent = Array();
while ($row = mysql_fetch_array($result) {
    $arr = Array(
        'shortrank' => $row['shortrank'],
        'shortname' => $row['shortname'],
        'taxonid' => $row['taxon_id'],
        'parentid' => $row['parent_id']
        );
    $arrOutput[] = $arr;
    if (!empty($row['parent_id'])) {
        $arrParent[$row['parent_id']] = $arr;
    }
}
// $arrOutput is now the final array with all the results and you can loop through it like you do in your original code. When looping, the parent can directly be accessed using parent_id as the associative key.
foreach ($arrOutput as $arr) {
    $elementName = $arr['shortname'];
    $elementRank = $arr['shortrank'];
    $parentName = $arrParent[$arr['parentid']]['shortname'];
    $parentRank = $arrParent[$arr['parentid']]['shortrank'];
}

希望这是有道理的!当然,只有在原始查询开销较大的情况下才需要上述内容。

注意:上面的代码没有经过测试,我只希望它能正常工作。可能需要进行细微的更改或修复;-)