perl icon

Rose::DB::Object - High Performance Perl ORM

Posted in , , Thu, 01 Jun 2006 21:22:00 GMT

In the area of Perl ORM (object relational mappers), there are essentially three players: Class::DBI, DBIx::Class and Rose::DB::Object. Of the three, Rose::DB::Object (a.k.a. RDBO) is known to be the fastest, running just 2-4 times the speed of straight DBI in many tests (albeit using an unloaded database). DBIx::Class is known as the most extensible and flexible. Class::DBI is considered outdated (e.g. it doesn't support JOINs) and to be avoided by many. RDBO is the fastest because speed is it's primary design consideration, implementing many perl and DBI-level optimizations. The design philosophy is described as:

Basically, any work that can be done "up-front" (or at least "infrequently") is done in order to keep the frequently used runtime code path very tight. - John Siracusa

RDBO's implementation accomplishes this feat in several ways:

  1. aggressive code inlining: method calls can be very expensive and RDBO goes to great lenghts to avoid this. The get_objects method in Rose::DB::Object:Manager is 2129 lines long.
  2. extensive caching of "derived metadata", e.g. commonly used SQL query strings, column lists, etc.
  3. extensive use of "the 'fast path' in DBI, such as always using bind_col() and fetch() to retrieve data instead of fetchrow_array(), unbound calls to fetchrow_arrayref(), or fetchrow_hashref()."
  4. "compiling down" accessor and mutator methods, both with and without triggers, to an optimized form in order to shorten the code path.

Achieving this high performance has resulted in some compromises. They include:

  1. the code is harder to maintain and extend, resulting in a smaller community of contributors.
  2. aggregate functions and other queries that do not return table rows (e.g. GROUP BY, HAVING, etc.) are not natively supported yet. A previous entry, Rose::DB::Object - aggregates, describes how to implement aggregates with RDBO.

Perl has a TIMTOWTDI tradition and ORMs are no exception. The primary alternative, DBIx::Class, is designed with extensibility as it's primary consideration and addresses the compromises RDBO has made. The implementation gives up some perl execution speed to RDBO to gain this extensibility while generating roughly equivalent SQL for a similar database load. Both RDBO and DBIC are much faster than Class::DBI. The extensibility philosophy has resulted in an alternative ORM that is more flexible, supports aggregate functions and has a larger community of committers relative to RDBO.

RDBO should be a strong contender if you want the fastest Perl ORM and can accept the design decisions it has made to achieve that performance. If you would like some extra capability and can give up some perl execution speed in your web nodes, it may be worthwhile to evaluate some alternatives. - High Performance Perl ORM digg:Rose::DB::Object - High Performance Perl ORM reddit:Rose::DB::Object - High Performance Perl ORM spurl:Rose::DB::Object - High Performance Perl ORM wists:Rose::DB::Object - High Performance Perl ORM simpy:Rose::DB::Object - High Performance Perl ORM newsvine:Rose::DB::Object - High Performance Perl ORM blinklist:Rose::DB::Object - High Performance Perl ORM furl:Rose::DB::Object - High Performance Perl ORM fark:Rose::DB::Object - High Performance Perl ORM blogmarks:Rose::DB::Object - High Performance Perl ORM Y!:Rose::DB::Object - High Performance Perl ORM smarking:Rose::DB::Object - High Performance Perl ORM magnolia:Rose::DB::Object - High Performance Perl ORM segnalo:Rose::DB::Object - High Performance Perl ORM


perl icon

Rose::DB::Object - aggregates

Posted in , , Thu, 01 Jun 2006 00:29:00 GMT

One of the advantages DBIx::Class has over Rose::DB::Object (RDBO) is that it natively handles GROUP BY, HAVING, etc. I use GROUP BY a lot so I asked John Siracusa how to do aggregate functions such as count and sum using GROUP BY with RDBO.

RDBO doesn't have native support for aggregates because it's designed to return row objects and the results of aggregate functions are not rows in any table. In the future RDBO may have a built-in get_results() Manager method that returns "data" instead of row objects, but for now there are two alternatives (quotes by Siracusa):

  1. Manager methods: "the RDBO way to do queries that have aggregates is to create a manager method that runs the desired query and returns the results. you can use the RDBO query builder to constrict the SQL if you want, the where part, for example"
  2. Views: "the other way is to make a view and have RDBO front that view as if it were a table letting the db do the aggregating part under the covers [...] big aggregate queries tend to be slow vs. a good view in a database that supports them well" - aggregates digg:Rose::DB::Object - aggregates reddit:Rose::DB::Object - aggregates spurl:Rose::DB::Object - aggregates wists:Rose::DB::Object - aggregates simpy:Rose::DB::Object - aggregates newsvine:Rose::DB::Object - aggregates blinklist:Rose::DB::Object - aggregates furl:Rose::DB::Object - aggregates fark:Rose::DB::Object - aggregates blogmarks:Rose::DB::Object - aggregates Y!:Rose::DB::Object - aggregates smarking:Rose::DB::Object - aggregates magnolia:Rose::DB::Object - aggregates segnalo:Rose::DB::Object - aggregates

no comments