2012-07-28 75 views
0

我有一个脚本,应该通过一个mysql数据库运行,并预先形成一个'test'on案件。简化数据库包含代表人员出行的记录。每个记录都是辛格尔之旅。但我只想使用往返旅行。所以我需要搜索数据库并且匹配两次彼此的旅程;去某个地方旅行和旅行。查询大型mysql数据库

该脚本工作正常。问题是数据库包含600.000多个案例。我知道这应该尽可能避免。但为了此脚本的目的以及稍后使用数据库记录,所有内容都必须粘在一起。

使用MAMP在我的iMac上执行时,执行脚本现在需要几个小时。当然,我确信它可以使用大量的内存etcetare。

我的问题是如何加快速度,最好的方法是什么?

这里的剧本我现在所拥有的:

$table   = $_GET['table'];     
$output = '';     
//Select all cases that has not been marked as invalid in previous test   
$query = "SELECT persid, ritid, vertpc, aankpc, jaar, maand, dag FROM MON.$table WHERE reasonInvalid != '1' OR reasonInvalid IS NULL";   
$result = mysql_query($query)or die($output .= mysql_error());      
$totalCountValid = '';   
$totalCountInvalid = '';   
$totalCount = '';     
//For each record:   
while($row = mysql_fetch_array($result)){     
    $totalCount += 1;     
    //Do another query, get all the rows for this persons ID and that share postal codes. Postal codes revert between the two trips     
    $persid     = $row['persid'];     
    $ritid     = $row['ritid'];     
    $pcD     = $row['vertpc'];     
    $pcA     = $row['aankpc'];     
    $jaar     = $row['jaar'];     
    $maand     = $row['maand'];     
    $dag     = $row['dag'];   
    $thecountquery = "SELECT * FROM MON.$table WHERE persid=$persid AND vertpc=$pcA AND aankpc=$pcD AND jaar = $jaar AND maand = $maand AND dag = $dag";     
    $thecount    = mysql_num_rows(mysql_query($thecountquery));     
    if($thecount >= 1){       
     //No worries, this person ID has multiple trips attached        
     $totalCountValid += 1;     
    }else{       
     //Ow my, the case is invalid!       
    $totalCountInvalid += 1;       
    //Call the markInvalid from functions.php       
    $totalCountValid += 1;       
    markInvalid($table, '2', 'ritid', $ritid);     
    }   
}     
//Echo the result   
$output .= 'Total cases: '.$totalCount.'<br>Valid: '.$totalCountValid.'<br>Invalid: '.$totalCountInvalid;     echo $output; 
+1

不清楚脚本的结果是什么;对表结构的解释也会有所帮助 – Andreas 2012-07-28 09:22:18

+0

结果是有些情况被标记为“无效”,就是这样。我可以提供db结构,但它很大(超过100列) – 2012-07-28 09:51:50

+0

您可以显示markInvalid()函数的代码吗? – Jocelyn 2012-07-28 10:20:42

回答

2

你的基本问题是,你正在做以下。

1)获取所有未被标记为无效的案例。
2)循环遍历步骤1)中获得的案例。

您可以轻松完成的任务是将针对1)和2)所写的查询组合在一个查询中,并对数据进行循环。这会加速一些事情。

请注意以下提示。

1)选择所有列并不是一件好事。数据遍历网络需要大量的时间。我建议用你真正需要的所有列替换通配符。

SELECT * <ALL_COlumns>

2)使用索引 - 难溶,有效且适当。了解何时使用它们以及何时不使用它们。

3)如果可以,请使用视图。
4)启用MySQL slow query log以了解您需要处理和优化哪些查询。

log_slow_queries = /var/log/mysql/mysql-slow.log 
long_query_time = 1 
log-queries-not-using-indexes 

5)使用正确的MySQL字段类型和存储引擎(非常非常重要)
6)使用EXPLAIN分析查询 - 解释是MySQL的一个有用的命令,它可以为您提供有关如何一些伟大的细节运行查询,使用哪个索引,需要检查多少行,以及是否需要执行文件排序,临时表和其他您想避免的令人讨厌的事情。

祝你好运。

+0

3)如果可以的话,使用视图。 我不会推荐它,除非你做一些像样的测试来验证视图会有所帮助。 MySql有一个令人讨厌的习惯,把视图物化为没有索引的临时表,并加入这个临时表。这可能比其他方法慢得多。 我目前正在优化对4GB数据库的查询,一些最棘手的问题是使用视图的查询。 – 2012-11-07 15:21:50