2012-07-28 4 views
0

mysql 데이터베이스를 통해 실행하고 특정 '테스트'를 수행해야하는 스크립트가 있습니다. 단순화 된 데이터베이스는 사람이 만든 여행을 나타내는 레코드를 포함합니다. 각 레코드는 독창적 인 여행입니다. 그러나 나는 원정 여행 만하고 싶다. 그래서 나는 데이터베이스를 검색하고 서로에게 두 번의 여행을 매치시켜야합니다. 특정 위치에서 여행 및 여행.큰 mysql 데이터베이스에 대한 쿼리

스크립트가 제대로 작동합니다. 문제는 데이터베이스에 600,000 개 이상의 사례가 포함되어 있다는 것입니다. 가능하다면 피해야한다는 것을 알고 있습니다. 그러나 나중에이 스크립트와 데이터베이스 레코드를 사용하기 위해서는 모든 것이 함께해야합니다.

MAMP를 사용하여 iMac에서 실행할 때 스크립트를 실행하는 데 몇 시간이 걸립니다. 물론 나는 많은 메모리를 사용할 수 있다고 확신했다.

제 질문은 어떻게하면 속도를 높일 수 있습니까?이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

$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

+0

결과는 어떤 경우가 '잘못된'으로 표시된다는 것입니다. 나는 DB 구조를 제공 할 수 있지만 거대한 (100 열 이상) –

+0

markInvalid() 함수의 코드를 표시 할 수 있습니까? – Jocelyn

답변

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)
6)를 사용하여 쿼리를 분석하기 위해 EXPLAIN 올바른 MySQL의 필드 유형과 아주 아주 중요한 스토리지 엔진()를 사용 - EXPLAIN 당신에게 방법에 대한 몇 가지 좋은 정보를 제공 할 수있는 MySQL의에서 유용한 명령은 질의 실행 여부, 사용 된 색인, 검사 할 행 수 및 파일 정렬, 임시 테이블 및 피할 수있는 기타 불쾌한 일을해야하는지 여부를 결정합니다.

행운을 빈다.

+0

3) 가능한 경우보기를 사용한다. 보기가 도움이되는지 확인하기 위해 적절한 테스트를 거치지 않는 한 권장하지 않습니다. MySql은 인덱스가없는 임시 테이블로 뷰를 구체화하고 이에 합류하는 불쾌한 습관을 가지고 있습니다. 이 방법은 다른 방법보다 훨씬 느릴 수 있습니다. 현재 4GB 데이터베이스에서 쿼리를 최적화하고 있으며 가장 까다로운 문제 중 일부는 뷰를 사용하는 쿼리와 관련이 있습니다. –

관련 문제