복붙노트

PDO :: fetchAll 대 PDO :: 루프에서 가져 오기

PHP

PDO :: fetchAll 대 PDO :: 루프에서 가져 오기

그냥 빠른 질문입니다.

루프에서 PDO :: fetchAll ()과 PDO :: fetch ()를 사용하는 것 사이에 성능 차이가 있습니까 (큰 결과 집합에 대해)?

차이가 나는 경우 사용자 정의 클래스의 객체로 가져 오는 중입니다.

필자의 초기 무식한 가정은 PDO가 하나의 명령문에서 여러 작업을 수행 할 수 있기 때문에 mysql_query가 하나의 명령문 만 실행할 수 있기 때문에 fetchAll이 더 빠를 수도 있다는 것입니다. 그러나 나는 PDO의 내부 동작에 대한 지식이 거의 없으며 문서는 이에 대해 아무 말도하지 않으며 fetchAll ()이 단순히 배열에 덤프 된 PHP 측 루프인지 아닌지에 대해 말하지 않습니다.

어떤 도움이 필요합니까?

해결법

  1. ==============================

    1.200k 임의 레코드가있는 작은 벤치 마크. 예상대로 fetchAll 메서드는 더 빠르지 만 더 많은 메모리가 필요합니다.

    200k 임의 레코드가있는 작은 벤치 마크. 예상대로 fetchAll 메서드는 더 빠르지 만 더 많은 메모리가 필요합니다.

    Result :
    fetchAll : 0.35965991020203s, 100249408b
    fetch : 0.39197015762329s, 440b
    

    사용 된 벤치 마크 코드 :

    <?php
    // First benchmark : speed
    $dbh = new PDO('mysql:dbname=testage;dbhost=localhost', 'root', '');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql = 'SELECT * FROM test_table WHERE 1';
    $stmt = $dbh->query($sql);
    $data = array();
    $start_all = microtime(true);
    $data = $stmt->fetchAll();
    $end_all = microtime(true);
    
    $stmt = $dbh->query($sql);
    $data = array();
    $start_one = microtime(true);
    while($data = $stmt->fetch()){}
    $end_one = microtime(true);
    
    // Second benchmark : memory usage
    $stmt = $dbh->query($sql);
    $data = array();
    $memory_start_all = memory_get_usage();
    $data = $stmt->fetchAll();
    $memory_end_all = memory_get_usage();
    
    $stmt = $dbh->query($sql);
    $data = array();
    $memory_end_one = 0;
    $memory_start_one = memory_get_usage();
    while($data = $stmt->fetch()){
      $memory_end_one = max($memory_end_one, memory_get_usage());
    }
    
    echo 'Result : <br/>
    fetchAll : ' . ($end_all - $start_all) . 's, ' . ($memory_end_all - $memory_start_all) . 'b<br/>
    fetch : ' . ($end_one - $start_one) . 's, ' . ($memory_end_one - $memory_start_one) . 'b<br/>';
    
  2. ==============================

    2.필자가 사실로 알고있는 PHP에 관한 한 가지 사실은 당신이 구현하는 함수가 거의 항상 PHP보다 느릴 것이라는 것입니다. 이것은 PHP에서 무언가가 구현되었을 때 C가 가지고있는 컴파일 시간 최적화 (PHP가 작성된 것)가없고 PHP 함수 호출의 오버 헤드가 높기 때문입니다.

    필자가 사실로 알고있는 PHP에 관한 한 가지 사실은 당신이 구현하는 함수가 거의 항상 PHP보다 느릴 것이라는 것입니다. 이것은 PHP에서 무언가가 구현되었을 때 C가 가지고있는 컴파일 시간 최적화 (PHP가 작성된 것)가없고 PHP 함수 호출의 오버 헤드가 높기 때문입니다.

  3. ==============================

    3.아치

    아치

    // $data in this case is an array of rows;
    
    $data = $stmt->fetchAll();
    
    
    // $data in this case is just one row after each loop;
    
    while($data = $stmt->fetch()){}
    
    
    // Try using
    
    $i = 0;
    
    while($data[$i++] = $stmt->fetch()){}
    

    메모리 차이가 무시할 수 있어야합니다.

  4. ==============================

    4."메모리 풋 프린트"를 측정하는 모든 벤치 마크는 실제로 아주 간단합니다.

    "메모리 풋 프린트"를 측정하는 모든 벤치 마크는 실제로 아주 간단합니다.

    기본적으로 PDO는 모든 것을 메모리에로드하지만 fetch 또는 fetchAll을 사용하면 상관하지 않습니다. 버퍼링되지 않은 쿼리의 이점을 실제로 얻으려면 PDO에게 버퍼링되지 않은 쿼리를 사용하도록 지시해야합니다.

    $ db-> setAttribute (PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY, false);

    이 경우 스크립트의 메모리 사용 공간에 큰 차이가 나타납니다.

  5. ==============================

    5.Mihai Stancu가 말했듯이, fetchAll은 fetch + while을 이기지 만 메모리가 거의 없습니다.

    Mihai Stancu가 말했듯이, fetchAll은 fetch + while을 이기지 만 메모리가 거의 없습니다.

    Result : 
    fetchAll : 0.160676956177s, 118539304b
    fetch : 0.121752023697s, 118544392b
    

    위의 결과를 올바르게 실행하면서 얻었습니다.

    $i = 0;
    while($data[$i++] = $stmt->fetch()){
        //
    }
    

    따라서 fetchAll은 메모리를 적게 소비하지만 fetch +는 더 빠릅니다! :)

  6. ==============================

    6.하지만 가져온 데이터를 배열에 저장하는 경우 메모리 사용량은 동일 할 것입니다.

    하지만 가져온 데이터를 배열에 저장하는 경우 메모리 사용량은 동일 할 것입니다.

    <?php
    define('DB_HOST', 'localhost');
    define('DB_USER', 'root');
    define('DB_PASS', '');
    // database to use
    define('DB', 'test');
    try
    {
       $dbh = new \PDO('mysql:dbname='. DB .';host='. DB_HOST, DB_USER, DB_PASS);   $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
       $sql = 'SELECT * FROM users WHERE 1';
       $stmt = $dbh->query($sql);
       $data = array();
       $start_all = microtime(true);
       $data = $stmt->fetchAll();
       $end_all = microtime(true);
    
       $stmt = $dbh->query($sql);
       $data = array();
       $start_one = microtime(true);
       while($data = $stmt->fetch()){}
       $end_one = microtime(true);
    
       // Second benchmark : memory usage
       $stmt = $dbh->query($sql);
       $data = array();
       $memory_start_all = memory_get_usage();
       $data = $stmt->fetchAll();
       $memory_end_all = memory_get_usage();
    
       $stmt = $dbh->query($sql);
       $data = array();
       $memory_end_one = 0;
       $memory_start_one = memory_get_usage();
       while($data[] = $stmt->fetch()){
         $memory_end_one = max($memory_end_one, memory_get_usage());
       }
    
       echo 'Result : <br/>
       fetchAll : ' . ($end_all - $start_all) . 's, ' . ($memory_end_all - $memory_start_all) . 'b<br/>
       fetch : ' . ($end_one - $start_one) . 's, ' . ($memory_end_one - $memory_start_one) . 'b<br/>';
    }
    catch ( PDOException $e )
    {
       echo $e->getMessage();
    }
    ?>
    
    Result : 
    fetchAll : 2.6941299438477E-5s, 9824b
    fetch : 1.5974044799805E-5s, 9824b
    
  7. ==============================

    7.나는 이것이 오래된 주제라는 것을 알고 있지만, 나는 같은 질문을 가지고 이것을 가로 질렀다. 내 자신의 간단한 "벤치 마크"를 실행하고 다른 사람들이 여기에 쓴 것을 읽은 것은 이것이 정확한 과학이 아니며 품질, 가벼운 코드 작성을 위해 노력해야하지만 시작시 너무 많은 시간을 낭비하지 않는다는 결론에 도달했습니다 프로젝트의

    나는 이것이 오래된 주제라는 것을 알고 있지만, 나는 같은 질문을 가지고 이것을 가로 질렀다. 내 자신의 간단한 "벤치 마크"를 실행하고 다른 사람들이 여기에 쓴 것을 읽은 것은 이것이 정확한 과학이 아니며 품질, 가벼운 코드 작성을 위해 노력해야하지만 시작시 너무 많은 시간을 낭비하지 않는다는 결론에 도달했습니다 프로젝트의

    내 제안은 : (베타?) 코드를 실행하여 데이터를 수집 한 후 최적화를 시작하십시오.

    내 간단한 벤치 마크에서 (단지 테스트 실행 시간) 나는 결과가 5 %와 50 %의 차이가 있습니다. 동일한 스크립트에서 두 옵션을 모두 실행하지만 fetchall을 실행하면 처음에는 fetchall보다 빠르며 그 반대도 마찬가지입니다. (나는 그들을 단발하고 몇 백 번 실행하여 중앙값과 평균값을 얻고 비교해야한다는 것을 알고 있지만, 처음에 말한 것처럼 - 나는 내 경우에 그렇게하기 시작했다는 결론을 내렸다.)

  8. from https://stackoverflow.com/questions/2770630/pdofetchall-vs-pdofetch-in-a-loop by cc-by-sa and MIT license