[Dbix-class] Weird RelationShip => SQL behavior and Performance Issue

Lee Standen nom at standen.id.au
Thu May 31 11:04:11 GMT 2007


With regards to performance, I'd be looking at whether it's the database 
or the code which is causing the delay...

If you don't have appropriate indexing, or the query doesn't work well 
on your particular database, then it's going to be painfully slow no 
matter how well DBIC handles it.




Benoit Plessis wrote:
> 
> 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/dbix-class@lists.rawmode.org/



More information about the Dbix-class mailing list