2016-08-02 4 views
0

mysql에서 레코드를 가져 오는 while 루프를 사용하고 있습니다. 우연히 올려 놓은 로그를 재설정하는 것이므로 DB의 백업에서 ID와 타임 스탬프를 가져 와서 해당 값으로 프로덕션 테이블을 업데이트하여 이전 레코드를 수정합니다.while 루프를 사용하는 PHP 메모리

이 로그 테이블에 12,545,628 개의 레코드가 있기 때문에 메모리 사용량을 제한하고이 솔루션의 사용량을 줄 이길 바랬습니다. ID와 타임 스탬프 필드 만 가져 오면 1GB의 메모리를 통해 빠져 나갑니다.

메모리 사용량을 한 번에 하나의 레코드로 제한합니까, 아니면 모든 ID 및 타임 스탬프를 똑바로 뽑아 내고이를 사용하고 있습니까?

$sql = 'SELECT id, timestamp FROM log_people WHERE 1'; 
$Test->sqlQuery($sql); 

while ($testdb = $Test->sth->fetch(PDO::FETCH_ASSOC)) { 
    $Prod->beginTransaction(); 

    try { 
     $sql2 = 'UPDATE log_people SET timestamp = "'.$testdb['timestamp'].'" WHERE id = '.$testdb['id']; 
     $Prod->sqlQuery($sql2); 


    } catch (exception $err) { 
     $Prod->rollback(); 
     echo $err->getMessage(); 
    } 
} 

난 그냥 당겨 한 번에 하나 개의 레코드를 수정하기 위해 아래의 코드를 일을해야 (내가 설정 데이터베이스 클래스 PDO를 이상하게 보일 수 있도록했습니다)? 문제에

while ($count < 12545628){ 
    $sql = 'SELECT id, timestamp FROM log_people WHERE id ='.$count; 
    $Test->sqlQuery($sql); 
    $testdb = $Test->sth->fetch(PDO::FETCH_ASSOC) 

$Prod->beginTransaction(); 

try { 
    $sql2 = 'UPDATE log_people SET timestamp = "'.$testdb['timestamp'].'" WHERE id = '.$testdb['id']; 
    $Prod->sqlQuery($sql2); 
    $count++; 


} catch (exception $err) { 
     $Prod->rollback(); 
     //return $err->getMessage(); 
     echo $err->getMessage(); 
    } 

}

+1

그럼 왜 모든 레코드를 '선택'해야합니까? 모든 기록을 업데이트해야하는 이유는 무엇입니까? –

+1

백업 테이블의 복사본을 동일한 DB에두고 SQL을 사용하여 프로덕션 테이블을 업데이트하면이 작업을 훨씬 빠르고 쉽게 수행 할 수 있습니까? PHP에서 왜 그렇게합니까? –

답변

0

, 당신은 같은 이전 값으로 테이블을 갱신한다. 메모리 측면에서 php의 메모리 제한은 php.ini 또는 PHP 코드로 정의 할 수 있습니다. 두 번째 코드는 첫 번째와 비교할 때 메모리가 효율적이지만 각 ID에 대해 별도의 쿼리가 있기 때문에 시간이 많이 걸립니다.

0

또한 이러한 레코드를 업데이트 할 때 모든 레코드를 선택해야하는 이유를 이해할 수 없습니다. 어쨌든 메모리 사용을 관리하는 데 도움이되는 몇 가지 팁이 있습니다.
첫 번째 점 스크립트의 메모리가 부족한 곳을 알려주는 함수가 있으며이 함수를 사용하여 확인할 수 있습니다 memory_get_peak_usage();.
두 번째 점 null을 설정 해제하는 것과 함께 vars에 null을 다시 할당 할 수도 있습니다. unset(); 함수는 가비지 수집기가 라운드를 수행 할 때 유용하지만 unset(); 함수는 단순히 데이터에 대한 변수 참조를 파괴하지만, 데이터는 여전히 메모리에 존재하며 PHP는 더 이상 포인터가 없어도 사용중인 메모리를 보게됩니다. 해결 방법 : 적어도 가비지 수집기가 데이터를 보관할 때까지 변수에 null을 할당하여 데이터를 지 웁니다. $ var = null; unset()을 사용할 수도 있습니다. 변수 포인터 설정을 해제 할 수 있지만 메모리 사용에 약간의 차이는 내가 볼 수있는만큼 지금까지이 :

unset($var); 


세 번째 점하면 객체의 처분에 개체 참조를 폭파함으로써 그렇게 할 수있는 또 다른 방법 .

protected function __distruct() 
{ 
    $this-&gt;childObject = null; 
} 
관련 문제