PHP查询运行缓慢,并切断非常大的MySQL数据库中的值

时间:2012-02-20 03:41:36

标签: php mysql large-data-volumes

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

我正在尝试使用PHP以某种格式使用echo“function”呈现该数据,并使用{$ variable}放置变量。

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

我在谷歌浏览器中运行了php文件,它在相当不错的core2duo机器上运行了大约1个小时。

但结果集停止在大约18,000个条目 - 顺便说一句,我对查询没有限制。

我的问题最重要的部分是如何运行此文件以获得所有结果?我不想坐在那里反复设置偏移量,如果有另一种方式,我将非常感激。

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

由于

更新

<?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";
?>

1 个答案:

答案 0 :(得分:1)

阅读以下几行,它似乎不是一个缓慢的查询问题。

“我在谷歌浏览器中运行了php文件,它在相当不错的core2duo机器上运行了大约1个小时。 但结果集停止在大约18,000个条目 - 我对查询没有任何限制“

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

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

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

编辑1 - 我试图在您的查询上稍微锻炼一下。既然你想要元素的名称和它的父名,我认为可以在更简单的查询中完成它而不需要两次连接相同的表。它需要编写一些额外的逻辑。

我从查询中学到很少的观​​察结果:

  1. 元素及其父名称均来自同一个表taxon_name_element
  2. 还有另一个列“rank”,它也来自同一个表taxonomic_rank,用于元素及其父元素
  3. 从这个特定的连接taxon_name_element.parent_id = tne.taxon_id,我了解到元素及其父元素在同一个表中`taxon_name_element“
  4. 现在让我们看一下更简单的查询:

    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'];
    }
    

    希望有道理!好吧,只有在原始查询很昂贵的情况下才需要上述课程。

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