[CDBI] Why does CDBI not populate the object on insert

Michael G Schwern schwern at pobox.com
Fri Mar 6 06:20:00 GMT 2009


Bill Moseley wrote:
>> Honestly, lazy loading is probably the biggest architectural mistake I made in
>> CDBI.  It seemed like a good idea at the time in 1999, with limited memory and
>> I was working on a message storage system (lots of small headers, big body)
>> but honestly it made the code way more complicated than it should be and
>> probably drags performance down more than it speeds up.  I should have just
>> made each message join from header and body tables but that would have
>> required good join support early on and I suck at joins.
> 
> Is the lazy loading expensive when not used? That is where Essential
> is tuned for the columns used?

Yes.  Rather than the getter just returning $obj->{$col} it has to check if
its been loaded or not.  This might not seem like much, but if you have an app
that calls accessor a lot it gets nasty.  And there's code like that all over,
you can't just read from %{$obj->{cols}}.

Also, rather than just checking $obj->{is_loaded}{$col} it does quite a bit
more work.  Look at how get() is implemented.

sub get {
        my $self = shift;
        return $self->_croak("Can't fetch data as class method") unless ref $self;

        my @cols = $self->_find_columns(@_);
        return $self->_croak("Can't get() nothing!") unless @cols;

        if (my @fetch_cols = grep !$self->_attribute_exists($_), @cols) {
                $self->_flesh($self->__grouper->groups_for(@fetch_cols));
        }

        return $self->_attrs(@cols);
}

That could probably have some major optimization.  I'm not sure what the call
to _find_columns() is about.  And $self->_attribute_exists($col) is nothing
but exists $self->{$col}.

The current edition of CDBI has some over encapsulation leading to performance
drags.

Also it would probably make sense for get() to be optimized into get_one() and
get_many().

Finally, CDBI could be smart, recognize that a class is not making use of lazy
loading and use an optimized accessor.


>> Consider using Class::DBI::Sweet or DBIx::Class both of which I
>> believe can model the above as a join instead of a string of
>> selects.
> 
> One of the reasons I still like CDBI is that it's a pretty
> simple ORM, and when I need more complex joins (which is very common
> in anything but the simplest application) I use set_sql().  I find SQL
> a nice clean way to write database queries. ;)

Seek professional help.

Speaking of writing SQL, I've heard good things about Fey.
http://search.cpan.org/dist/Fey


-- 
170. Not allowed to "defect" to OPFOR during training missions.
    -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army
           http://skippyslist.com/list/



More information about the ClassDBI mailing list