hi everyone,

I'm knew to DBIx::Class (discovered with the Catalyst framework) but
i think it's terrible !

Anyway i encountered two gotchas while using the thing and here they are:

1/ Relationships.

Let's say we have 3 tables and two relation:
   table1.rel1 is a *might_have* on table2
   table2.rel2 is a *belongs_to* on table3

when doing someting like that:
$schema->resultset('Table1') -> search (undef, { prefetch => { 'table2' => 'table3' } });
the generated SQL code will be something like that:

/FROM table1 LEFT JOIN table2 ON (table1.f1 = table2.f1) JOIN table3 ON (table2.f2 = table3.f2)

/The problem (at least with MySQL 5) is the following: If they are entries in table1 with no corresponding entries in table2 (witch is the purpose of *might_have* iiuc) the second JOIN on table3 will remove thoses
entries from the resulting set.

Eg:
      SELECT COUNT(*) FROM table1 LEFT JOIN table2 => 3000 entries
      SELECT COUNT(*) FROM table2 JOIN table3            => 300 entries
then SELECT COUNT(*) FROM table1 LEFT JOIN table2 JOIN table3 will give 300 replies


2/ Performance weirdness

When i understood the previous fact i cuted my big search with prefetch on 10 tables as far as i can prefetch without 'losing' datas. Resulting in 5/6 more SQL queries for each loop.
   => this took 1min40s to process the whole dataset.

my $rs = $erp->resultset('Table1')->search(undef,
{ prefetch => ['rel1', { rel2 => [ 'rel3', 'rel4', 'rel5', 'rel6', ], }, ], });

while (my $e = $rs -> next) {

  ....;

  foreach my $s ($e->rel2->rel6()) {
        $datas = $s->rel7->nom();
if (my $b = $s->rel8()) { $datas = ( $b->rel9->nom() , $b->rel10->nom(), $b->rel11->nom() );
            }
    }
 }

}


So i tried to optimize this by creating another search+prefetch resultset on the last 5 tables which is build once per loop using result for the first set. There is the funny thing, it is slower than the first case by 70 sec (2min50s).

my $rs = $erp->resultset('Table1')->search(undef,
{ prefetch => ['rel1', { rel2 => [ 'rel3', 'rel4', 'rel5', 'rel6', ], }, ], });

while (my $e = $rs -> next) {

  ....;

my $rs2 = $erp->resultset('Table7')->search({ "me.num" => $e->rel2->num_table7() }, { prefetch => ['rel7', { rel8 => [ 'rel9', 'rel10', 'rel11' ] },]}); while (my $licence = $rs -> next()) {
        $datas = $s->rel7->nom();
if (my $b = $s->rel8()) { $datas = ( $b->rel9->nom() , $b->rel10->nom(), $b->rel11->nom() );
            }
    }
 }

}

I'm using perl and DBIx::Class as of debian/etch release (5.8.8-7 and 0.07003-1)
If u need mode informations feel free to ask.

Regards,
benoit

_______________________________________________
List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
Wiki: http://dbix-class.shadowcatsystems.co.uk/
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
Searchable Archive: http://www.mail-archive.com/[email protected]/

Reply via email to