Hallo, BTW Andreas: musst du per Exchange/Vodafone hier mitschreiben? Die fehlenden References/In-Reply-To sind doch etwas unschoen. Da ich deine Mails gerne lese und schaetze, wuerde ich mich freuen, wenn du auf einem anderen Wege hier mailen wuerdest und/oder den $Verantwortlichen beibiegen koenntest, dass sie Exchange, oder was auch immer du als "MUA" verwendest, RfC-konform konfigurieren sollen. Am Thu, 11 Nov 2004, Kyek, Andreas, VF-DE schrieb:
David Haller wrote: [..]
Evtl. waere es noch klarer, wenn du statt fetchrow_array ein fetchrow_hashref verwendest und dann [..] Allerdings ist das weniger performant als mit _arrayref oder _array.
Meine DBI Doku empfiehlt hier (wenn Performance interessant ist) folgendes Konstrukt zu verwenden:
--- cut here --- my sth = $dbh-prepare ...
my $sth = $dbh->prepare ...
$sth->execute ($username) or ...; $sth-bind_columns ( ($result_username, $result_pwd) ) or ...;
$sth->bind_columns(..);
while ($sth-fetch) {
while ($sth->fetch) { Sach ma, hast du noch keinen Kaffee gehabt? [..]
Laut Doku ist ein fetchrow_array oder auch ein fetchrow_hashref langsamer (aber das wird man erst bei richtigen Datenmengen bemerken können).
Hm. "Man nehme" ne DB mit 2 Spalten "user_id" und "login" (und ggfs. mehr Spalten). 'user' und 'pass' anpassen! Achtung: ueberlange Zeilen ab hier. ========================== perldbitest.pl =========================== #!/usr/bin/perl -w use strict; use Benchmark qw(cmpthese); use DBI; my $dbh; my $select = 'SELECT user_id,login FROM user WHERE user_id=?'; my @uids = ( eval "@ARGV" ); print STDERR "comparing for uids: @ARGV\n"; open(NULL, ">/dev/null") or die "cannot open /dev/null: $!"; $dbh = DBI->connect("DBI:mysql:somedatabase", 'user', 'pass) or die "$DBI::errstr"; cmpthese( 1000, { 'dbihashref' => sub { my $h; my $sth = $dbh->prepare($select); for ( @uids ) { $sth->execute($_); ( $h = $sth->fetchrow_hashref() ) && print NULL "$h->{user_id}, $h->{login}\n"; } $sth->finish(); }, 'dbiarrayref' => sub { my $a; my $sth = $dbh->prepare($select); for ( @uids ) { $sth->execute($_); ( $a = $sth->fetchrow_arrayref() ) && print NULL "$a->[0], $a->[1]\n"; } $sth->finish(); }, 'dbiarray' => sub { my @a; my $sth = $dbh->prepare($select); for ( @uids ) { $sth->execute($_); ( @a = $sth->fetchrow_array() ) && print NULL "$a[0], $a[1]\n"; } $sth->finish(); }, 'dbibind' => sub { my ($uid, $login); my $sth = $dbh->prepare($select); for ( @uids ) { $sth->execute($_); $sth->bind_columns( $uid, $login ); $sth->fetch() && print NULL "$uid, $login", "\n"; } $sth->finish(); } } ); $dbh->disconnect(); close(NULL); 1; ===================================================================== Die 'print NULL' dienen hier natuerlich zur Illustration wie man jeweils auf die Daten zugreift. Als Beispiel hier: ===================================================================== $ ./perldbitest.pl 55; ./perldbitest.pl 55 .. 59; ./perldbitest.pl 55 .. 100; ./perldbitest.pl 55 .. 200 comparing for uids: 55 Benchmark: timing 1000 iterations of dbiarray, dbiarrayref, dbibind, dbihashref... dbiarray: 1 wallclock secs ( 0.51 usr + 0.07 sys = 0.58 CPU) @ 1724.14/s (n=1000) dbiarrayref: 1 wallclock secs ( 0.55 usr + 0.06 sys = 0.61 CPU) @ 1639.34/s (n=1000) dbibind: 1 wallclock secs ( 0.50 usr + 0.02 sys = 0.52 CPU) @ 1923.08/s (n=1000) dbihashref: 1 wallclock secs ( 0.60 usr + 0.00 sys = 0.60 CPU) @ 1666.67/s (n=1000) Rate dbiarrayref dbihashref dbiarray dbibind dbiarrayref 1639/s -- -2% -5% -15% dbihashref 1667/s 2% -- -3% -13% dbiarray 1724/s 5% 3% -- -10% dbibind 1923/s 17% 15% 12% -- comparing for uids: 55 .. 59 Benchmark: timing 1000 iterations of dbiarray, dbiarrayref, dbibind, dbihashref... dbiarray: 3 wallclock secs ( 1.03 usr + 0.21 sys = 1.24 CPU) @ 806.45/s (n=1000) dbiarrayref: 2 wallclock secs ( 1.01 usr + 0.25 sys = 1.26 CPU) @ 793.65/s (n=1000) dbibind: 3 wallclock secs ( 0.94 usr + 0.18 sys = 1.12 CPU) @ 892.86/s (n=1000) dbihashref: 3 wallclock secs ( 1.40 usr + 0.24 sys = 1.64 CPU) @ 609.76/s (n=1000) Rate dbihashref dbiarrayref dbiarray dbibind dbihashref 610/s -- -23% -24% -32% dbiarrayref 794/s 30% -- -2% -11% dbiarray 806/s 32% 2% -- -10% dbibind 893/s 46% 12% 11% -- comparing for uids: 55 .. 100 Benchmark: timing 1000 iterations of dbiarray, dbiarrayref, dbibind, dbihashref... dbiarray: 20 wallclock secs ( 7.05 usr + 1.94 sys = 8.99 CPU) @ 111.23/s (n=1000) dbiarrayref: 20 wallclock secs ( 8.12 usr + 2.23 sys = 10.35 CPU) @ 96.62/s (n=1000) dbibind: 20 wallclock secs ( 7.12 usr + 2.11 sys = 9.23 CPU) @ 108.34/s (n=1000) dbihashref: 25 wallclock secs (10.84 usr + 1.93 sys = 12.77 CPU) @ 78.31/s (n=1000) Rate dbihashref dbiarrayref dbibind dbiarray dbihashref 78.3/s -- -19% -28% -30% dbiarrayref 96.6/s 23% -- -11% -13% dbibind 108/s 38% 12% -- -3% dbiarray 111/s 42% 15% 3% -- comparing for uids: 55 .. 200 Benchmark: timing 1000 iterations of dbiarray, dbiarrayref, dbibind, dbihashref... dbiarray: 61 wallclock secs (19.97 usr + 6.86 sys = 26.83 CPU) @ 37.27/s (n=1000) dbiarrayref: 61 wallclock secs (20.33 usr + 6.90 sys = 27.23 CPU) @ 36.72/s (n=1000) dbibind: 61 wallclock secs (21.81 usr + 6.85 sys = 28.66 CPU) @ 34.89/s (n=1000) dbihashref: 72 wallclock secs (30.05 usr + 7.48 sys = 37.53 CPU) @ 26.65/s (n=1000) Rate dbihashref dbibind dbiarrayref dbiarray dbihashref 26.6/s -- -24% -27% -29% dbibind 34.9/s 31% -- -5% -6% dbiarrayref 36.7/s 38% 5% -- -1% dbiarray 37.3/s 40% 7% 1% -- ===================================================================== Komischerweise(?) ist die bind-Variante gerade bei "groesseren" Datenmengen / Iterationen nicht die schnellste... Zumindest bei diesem Zugriffsmuster eben... Und wenn man nur eine UID abfraegt (siehe ersten Vergleich) ist sogar hashref schneller als arrayref... Ob fuer einen der Unterschied hashref zu arrayref oder array signifikant ist (unter Beachtung der besseren Lesbarkeit bei den hashref und bind Varianten) muss man wohl je nach Anwendung entscheiden. Die bind-Variante scheint aber wohl die Lesbarkeit mit der Performance zu kombinieren. Im konkreten Fall sollte man wohl selber mal einen Benchmark wie oben auf die DB loslassen ;) -dnh --
I hate black text on a white background on CRTs. Too damned bright. You're right. Black text on a black background is so much more restful. -- J. Bowden and Tanuki