PDO vs PDO :: fetchAll :: bir döngü içinde almak

6 Cevap php

Sadece hızlı bir soru.

(Büyük sonuç kümeleri için) bir döngü () getirilemedi :: PDO :: fetchAll () ve PDO kullanarak arasında herhangi bir performans farkı var mı?

Herhangi bir fark yaparsa ben, bir kullanıcı tanımlı sınıfın nesneleri içine getiriliyor ediyorum.

Benim ilk eğitimsiz varsayım mysql_query yalnızca birini idam ederken PDO bir deyimde birden çok işlemleri gerçekleştirebilirsiniz çünkü fetchAll hızlı olabilir oldu. Ancak ben PDO iç çalışmasını az bilgiye sahip ve belgeleri bu konuda hiçbir şey söylemiyor ve fetchAll () olsun veya olmasın sadece bir diziye dampingli bir PHP tarafı döngü.

Herhangi bir yardım?

6 Cevap

200k rasgele kayıtları ile küçük kriter. Beklendiği gibi, fetchAll yöntemi daha hızlı ama daha fazla bellek gerektirir.

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

Gösterge kod kullanılır:

<?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/>';

Ben doğru buldum PHP hakkında bir şey hemen hemen always kendinizi uygulamak bir işlevi hemen hemen her zaman PHP eşdeğer daha yavaş olmasıdır. Şey PHP uygulanan zaman C (PHP ile yazılmış olan) sahip olduğu tüm derleme zamanı iyileştirmeleri yoktur ve PHP fonksiyon çağrıları yüksek yükü var olmasıdır.

@ Arkh

// $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()){}

Bellek fark neglijable haline gelmelidir

Mihai Stancu Dediğim gibi fetchAll atım + süre almak olsa da, hemen hemen hiç hafıza fark yoktur.

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

Ben ise düzgün çalışan yukarıdaki sonuç var:

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

Yani fetchAll daha az bellek tüketiyor, ama süre hızlıdır + getir! :)

Eğer bir dizi zorlama veri depolama eğer Ama elbette, bellek kullanımı eşit olacaktır?

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

Ben bu eski bir konu olduğunu biliyorum, ama bu aynı soru olan rastlamak. Benim kendi basit "kriter" çalıştırın ve diğerleri ben bu kesin bir bilim değildir ve bir kalite, ışık kod yazmak için gayret ederken, başında çok fazla vakit hiçbir nokta olduğu sonucuna geldi buraya yazdıklarını okuduktan sonra Projenin.

Benim öneri: Bir süre için (? Beta) kodu çalıştırarak verileri toplayın ve sonra optimize başlayabilirsiniz.

Benim basit kriter (sadece test yürütme zamanı) ben sonuç HER yolları% 5 ve% 50 arasında değişen var ettik. Ben aynı komut iki seçeneği çalıştırdığınızda, ancak ilk tam tersi Fetchall daha hızlı ve olmuştur ederken + getir çalıştırdığınızda. (Ben tek ve çift yüz kere medyan almak ve ortalama ve sonra karşılaştırmak onları çalıştırmak gerekirdi biliyorum, ama - ben başında söylediğimiz gibi - Ben benim durumumda bunu yapmaya başlamak için çok erken olduğu sonucuna varmıştır.)