Further to my recent node that asked if bind was necessary, I can now answer the question, in a limited sense, for the performance of a very simple SELECT statement: not that much at all.
I first wrote code just to do a simple SELECT from the database, then copy and pasted that code and just changed the value passing in the execute method to a bind_param call. Then I copy and pasted those two subs and wrapped everything after the database connection in an eval. I expected the eval to be quite expensive, and the bind to be fairly cheap.
#!/usr/bin/perl -w # Test DB2 code re bind vs. no bind and eval vs. no eval. use strict; use DBI; use Benchmark qw(:all); our $database = "db"; our $user = "user"; our $password = "password"; { my $results = timethese(0, { 'noBindNoEval' => &noBindNoEval, 'bindNoEval' => &bindNoEval, 'noBindEval' => &noBindEval, 'bindEval' => &bindEval, },'none'); cmpthese($results); } sub noBindNoEval { my $dbh = DBI->connect("DBI:DB2:$database", $user, $password ); defined($dbh) or die "Unable to connect to database:".$DBI::errstr +; my $query = "SELECT * FROM table WHERE name = ? FOR READ ONLY"; my $sth = $dbh->prepare($query); $sth->execute("abeamish") or die "Execute failed:".$DBI::errstr; my $result = $sth->fetchrow_hashref; if ( defined ( $result ) ) { print "Found record for $result->{'NAME'}\n"; } $sth->finish; $dbh->disconnect; } sub bindNoEval { my $dbh = DBI->connect("DBI:DB2:$database", $user, $password ); defined($dbh) or die "Unable to connect to database:".$DBI::errstr +; my $query = "SELECT * FROM table WHERE name = ? FOR READ ONLY"; my $sth = $dbh->prepare($query); $sth->bind_param(1,"abeamish"); $sth->execute() or die "Execute failed:".$DBI::errstr; my $result = $sth->fetchrow_hashref; if ( defined ( $result ) ) { print "Found record for $result->{'NAME'}\n"; } $sth->finish; $dbh->disconnect; } sub noBindEval { my $dbh = DBI->connect("DBI:DB2:$database", $user, $password ); defined($dbh) or die "Unable to connect to database:".$DBI::errstr +; eval { my $query = "SELECT * FROM table WHERE name = ? FOR READ ONLY"; my $sth = $dbh->prepare($query); $sth->execute("abeamish") or die "Execute failed:".$DBI::errstr; my $result = $sth->fetchrow_hashref; if ( defined ( $result ) ) { print "Found record for $result->{'NAME'}\n"; } $sth->finish; }; if ($@) { print "Error encountered:".$DBI::errstr." $@"; } $dbh->disconnect; } sub bindEval { my $dbh = DBI->connect("DBI:DB2:$database", $user, $password ); defined($dbh) or die "Unable to connect to database:".$DBI::errstr +; eval { my $query = "SELECT * FROM table WHERE name = ? FOR READ ONLY"; my $sth = $dbh->prepare($query); $sth->bind_param(1,"abeamish"); $sth->execute() or die "Execute failed:".$DBI::errstr; my $result = $sth->fetchrow_hashref; if ( defined ( $result ) ) { print "Found record for $result->{'NAME'}\n"; } $sth->finish; }; if ($@) { print "Error encountered:".$DBI::errstr." $@"; } $dbh->disconnect; }
Update: Ignore this nonesense .. correct results are below, after tye's excellent response.
The results (editted to fit without wrapping) are as follows:
This tells me that no binding with an eval is the slowest combination, very closely followed by binding without the eval. 5% away is neither bind nor eval, and a little ahead of that combination is both bind and eval.Rate noBndEval bndNoEval noBndNoEval bndEval noBndEval 9655605/s -- -0% -5% -5% bndNoEval 9695347/s 0% -- -4% -5% noBndNoEval 10150483/s 5% 5% -- -1% bndEval 10203485/s 6% 5% 1% --
Fascinating. It makes sense that bind is faster, because DBI has to do less work. And if I think about how eval might be implemented, it's possible that it finds all of the .. or die .. fragments and short-circuits them, thus stream-lining the code and making it run faster.
Well, it's not the answer I expected, but at least now I have an answer that I've determined experimentally. Next, I want to look at what kind of type checking bind_param does.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Performance issues using bind and eval in DB2 accesses (noise)
by tye (Sage) on May 20, 2008 at 19:52 UTC | |
by talexb (Chancellor) on May 20, 2008 at 20:11 UTC | |
by andreas1234567 (Vicar) on May 21, 2008 at 05:39 UTC |