in reply to DBI do vs prepare

So I'm trying to figure out why, in the following example, Code1, which uses the prepare strategy, benchmarks slower than Code2, which uses repeated dos?

Your benchmark code has a severe flaw in that it measures quite a bit of argument packing and unpacking besides the DBI calls.

Replies are listed 'Best First'.
Re^2: DBI do vs prepare
by astaines (Curate) on Aug 13, 2006 at 23:57 UTC

    Not a clue as to why, but I agree with chromatic about your benchmark. In general whether prepare is worth doing depends on what you are talking to. The logic is that some databases have a very heavy overhead for setting up a query, which is what prepare does. So, for repetitive queries you suffer the pain once only. However, this isn't true for all databases, and you may only benefit if you have a lot of repetitive queries to work on.

    To progress you need a much purer benchmark to test exactly what you plan to do in the real world. This should be on of the last things you do in the course of development. This avoids the curse of Premature optimization!

    !-- Node text goes above. Div tags should contain sig only -->
    -- Anthony Staines

      I'm still not sure how I'd test without supplying the arguments. Perhaps you could give me an example?

      Actually I am trying to optimize an already functioning program. Code2 and UpdateDBIar are from the current program logic, but I thought I'd try something with the prepare strategy to see if it would be faster.

      Brian

Re^2: DBI do vs prepare
by BrianC (Acolyte) on Aug 13, 2006 at 23:51 UTC
    I'm not sure how to test the function without packing parameters. And I certainly can't use it without packing parameters. I guess it doesn't really matter if the "prepare/execute" is faster if the cost of implementation is considerably higher.

      I didn't test this code, but I rewrote it to be a lot more efficient and to copy a lot less information. I expect it to run substantially more quickly.

      sub UpdateDBIar2 { my ($queries, $args) = @_; use DBI; my $dbh = DBI->connect( "dbi:mysql:database=SchoolToolsDev;host=localhost;user=stadmin;passwor +d=stadmin" ) or die "Couldn't connect to database $DBI::errstr\n"; for my $query ( @$queries ) { my $sth = $dbh->prepare($query); for my $arg (@$args) { $sth->execute( $arg ); } } } my $crCode1 = sub { my @result = ( 10734 .. 10845 ); my @queries = map { "UPDATE Tests SET $_ = '1' WHERE ID = ?" } qw( Baseline Q1 Q2 Q3 Q4 ); UpdateDBIar2( \@queries, \@result ); };
        Thank you for this. Unfortunately, my simplified version of the actual code does not tell you that the result set is different for each quarter. They are five different arrays coming from an html form. That's why I need the extra for loop. I also want it generalized for an arbitrary number of placeholders.