答案 0 :(得分:39)
我想知道这个问题的答案,所以我快速写了benchmark script。
我建议您在自己的服务器上运行此基准测试,但是,对于单行结果,这是我的设置的典型结果:
对于大型数据集,这些结果是典型的:
查看关于git hub的评论,获取所有行确实改变了测试。
答案 1 :(得分:3)
我想知道当我要获取大量数据时,FETCH ASSOC是否更快;或者他们是一样的?
当您不需要时,不要获取大量数据。就是这样。
一旦你需要它 - 这些方法之间的微观差异将是你最不关心的。
答案 2 :(得分:3)
在另一个答案中发布的基准脚本正在计算prepare()和execute()到时间,因此我编写了一个脚本来仅测试获取时间。我有MySQL数据库,有大约100000行真实数据。 LongRow包含TEXT列(每行约4kB数据)。 ShortRow是(每行30个字节)。 FETCH_INTO使用具有所有列属性的预定义类。 PHP版本5.4。 MySQL 5.5.35。这里缺少一件事:一些运行的平均值。
Array ( [Items: 10] => Array ( [ShortRow] => Array ( [FETCH_INTO] => 0.0001068115234375 [FETCH_OBJECT] => 0.00013899803161621 [FETCH_COLUMN (STR8)] => 6.0081481933594E-5 [FETCH_COLUMN (INT)] => 5.8174133300781E-5 [FETCH_NUM] => 9.2029571533203E-5 [FETCH_ASSOC] => 9.8943710327148E-5 [FETCH_BOTH] => 0.00011897087097168 [FETCH_LAZY] => 6.3180923461914E-5 ) [LongRow] => Array ( [FETCH_INTO] => 0.00012779235839844 [FETCH_OBJECT] => 0.00016498565673828 [FETCH_COLUMN (TEXT)] => 4.9829483032227E-5 [FETCH_COLUMN (INT)] => 4.3153762817383E-5 [FETCH_NUM] => 0.00010180473327637 [FETCH_ASSOC] => 0.00010895729064941 [FETCH_BOTH] => 0.00013399124145508 [FETCH_LAZY] => 4.3869018554688E-5 ) ) [Items: 100] => Array ( [ShortRow] => Array ( [FETCH_INTO] => 0.00081610679626465 [FETCH_OBJECT] => 0.0011789798736572 [FETCH_COLUMN (STR8)] => 0.00040292739868164 [FETCH_COLUMN (INT)] => 0.00041294097900391 [FETCH_NUM] => 0.00067806243896484 [FETCH_ASSOC] => 0.00076103210449219 [FETCH_BOTH] => 0.00092482566833496 [FETCH_LAZY] => 0.00043201446533203 ) [LongRow] => Array ( [FETCH_INTO] => 0.0010471343994141 [FETCH_OBJECT] => 0.0013670921325684 [FETCH_COLUMN (TEXT)] => 0.00037693977355957 [FETCH_COLUMN (INT)] => 0.00030612945556641 [FETCH_NUM] => 0.00079894065856934 [FETCH_ASSOC] => 0.00094914436340332 [FETCH_BOTH] => 0.0011270046234131 [FETCH_LAZY] => 0.00031089782714844 ) ) [Items: 1000] => Array ( [ShortRow] => Array ( [FETCH_INTO] => 0.0082287788391113 [FETCH_OBJECT] => 0.0099248886108398 [FETCH_COLUMN (STR8)] => 0.0037147998809814 [FETCH_COLUMN (INT)] => 0.0038070678710938 [FETCH_NUM] => 0.006443977355957 [FETCH_ASSOC] => 0.0070838928222656 [FETCH_BOTH] => 0.008652925491333 [FETCH_LAZY] => 0.0039060115814209 ) [LongRow] => Array ( [FETCH_INTO] => 0.0092909336090088 [FETCH_OBJECT] => 0.011745929718018 [FETCH_COLUMN (TEXT)] => 0.0031650066375732 [FETCH_COLUMN (INT)] => 0.0025970935821533 [FETCH_NUM] => 0.0068809986114502 [FETCH_ASSOC] => 0.0087978839874268 [FETCH_BOTH] => 0.010183811187744 [FETCH_LAZY] => 0.0026650428771973 ) ) [Items: 10000] => Array ( [ShortRow] => Array ( [FETCH_INTO] => 0.067224025726318 [FETCH_OBJECT] => 0.086459159851074 [FETCH_COLUMN (STR8)] => 0.03191089630127 [FETCH_COLUMN (INT)] => 0.031462907791138 [FETCH_NUM] => 0.047988891601562 [FETCH_ASSOC] => 0.05333399772644 [FETCH_BOTH] => 0.065713882446289 [FETCH_LAZY] => 0.028834819793701 ) [LongRow] => Array ( [FETCH_INTO] => 0.12389183044434 [FETCH_OBJECT] => 0.15812706947327 [FETCH_COLUMN (TEXT)] => 0.03816294670105 [FETCH_COLUMN (INT)] => 0.035914897918701 [FETCH_NUM] => 0.1117901802063 [FETCH_ASSOC] => 0.10923099517822 [FETCH_BOTH] => 0.12394094467163 [FETCH_LAZY] => 0.030914068222046 ) ) )
这也是一个代码:
//Code is missing connect to DB
header('Content-Type: text/plain');
class testModel1 {
public $id;
public $invoice;
public $transaction;
public $creditedInvoice;
public $amount;
public $payment_type;
public $currency;
public $created;
public $timestamp;
}
class testModel2 {
public $id;
public $cid;
public $c_amount;
public $object;
public $person;
public $date;
public $type;
public $invoice_type;
public $version;
public $templateInvoice;
public $account;
public $variable_symbol;
public $number;
public $accounting_year;
public $amount;
public $currency;
public $comment;
public $data; //is a text column (avg size about 4kB)
public $created;
public $modified;
public $timestamp;
}
$items = array(10,100,1000,10000);
foreach($items as $item) {
$ivStmt = $pdo->prepare("SELECT * FROM `invoices_paying` LIMIT $item");
$ivStmt->execute(array('items'=>$item));
$out = array();
$testModel1 = new testModel1();
$ivStmt->setFetchMode(PDO::FETCH_INTO, $testModel1);
$start = microtime(true);
while($id = $ivStmt->fetch()) {
}
$end = microtime(true);
$out['FETCH_INTO'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetchObject()) {
}
$end = microtime(true);
$out['FETCH_OBJECT'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetchColumn(5)) {
}
$end = microtime(true);
$out['FETCH_COLUMN (STR8)'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetchColumn(0)) {
}
$end = microtime(true);
$out['FETCH_COLUMN (INT)'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_NUM)) {
}
$end = microtime(true);
$out['FETCH_NUM'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_ASSOC)) {
}
$end = microtime(true);
$out['FETCH_ASSOC'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_BOTH)) {
}
$end = microtime(true);
$out['FETCH_BOTH'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_LAZY)) {
}
$end = microtime(true);
$out['FETCH_LAZY'] = $end-$start;
$table['Items: '.$item]['ShortRow'] = $out;
}
foreach($items as $item) {
$ivStmt = $pdo->prepare("SELECT * FROM `invoices` LIMIT $item");
$ivStmt->execute(array('items'=>$item));
$out = array();
$testModel2 = new testModel2();
$ivStmt->setFetchMode(PDO::FETCH_INTO, $testModel2);
$start = microtime(true);
while($id = $ivStmt->fetch()) {
}
$end = microtime(true);
$out['FETCH_INTO'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetchObject()) {
}
$end = microtime(true);
$out['FETCH_OBJECT'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetchColumn(17)) {
}
$end = microtime(true);
$out['FETCH_COLUMN (TEXT)'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetchColumn(0)) {
}
$end = microtime(true);
$out['FETCH_COLUMN (INT)'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_NUM)) {
}
$end = microtime(true);
$out['FETCH_NUM'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_ASSOC)) {
}
$end = microtime(true);
$out['FETCH_ASSOC'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_BOTH)) {
}
$end = microtime(true);
$out['FETCH_BOTH'] = $end-$start;
$ivStmt->execute(array('items'=>$item));
$start = microtime(true);
while($id = $ivStmt->fetch(PDO::FETCH_LAZY)) {
}
$end = microtime(true);
$out['FETCH_LAZY'] = $end-$start;
$table['Items: '.$item]['LongRow'] = $out;
}
print_r($table);
答案 3 :(得分:2)
答案 4 :(得分:-2)
最后的回答是愚蠢的(“不要获取....”):如果你必须为大表或接口dbs表转换数据怎么办?
我更改了上面的基准测试代码,因为它没有正确测试IMHO(每个循环一个单独获取是不够的;-)),我将其替换为10000个记录x每个获取类型100个循环。
我添加了Fetch_class这是我自己的问题。 我添加了一个真正的类来确定后一个测试是否正确。
结果(已排序):
Array
(
[Lazy] => 88.43896484375
[Num] => 281.11694335938
[Assoc] => 310.59375
[Class] => 384.8310546875
[Obj] => 395.36401367188
[Both] => 411.62109375
)
懒惰值不完整,因为没有访问权限。 但“两者”实际上 HAS 影响
这是修改后的要点modified Benchmark code