On Nov 17, 2007, at 12:02 AM, Sharon Rosner wrote:

>
>> This code results in two database hits like so:
>>
>> I, [2007-11-16T13:15:11.468035 #1255]  INFO -- : INSERT INTO orders
>> ( `market`, `date`, `order_id`) VALUES ( 'ICE', '20071114', '9104')
>> I, [2007-11-16T13:15:11.468913 #1255]  INFO -- : SELECT * FROM orders
>> WHERE (`id` = 28838) LIMIT 1
>>
>> The order instance obviously already knows the primary key since it
>> uses it for the SELECT statement.
>
> Currently when you create a model record, it is SELECTed immediately
> after being INSERTed, in order to retrieve all the columns and any
> default values belonging to the model instance. I think this makes
> sense in many cases, but there's the performance penalty. If it's
> really important to you, I can look at offering an alternative
> behavior.

Yes, let's take a look at some alternatives. I agree that this  
behavior should be default. It certainly follows the Principle of  
Least Surprise. But for us performance-conscious folks, the extra  
select can oftentimes be superfluous particularly if we aren't using  
column defaults.

I took a look at the Sequel::Model definition for +save+ where +refresh 
+ does this immediate select. It would be handy if we could pass in  
optional parameters when defining our Models to selectively turn off  
this type of behavior. Here's an example:

class Order < Sequel::Model(:orders)
   set_schema do
     # column definitions...
   end

   performance_tune :disable_auto_refresh => true
end

module Sequel
   class Model
     attr_accessor :opts
     def performance_tune(opts)
       @opts = @opts.merge(opts)
     end

     # Creates or updates dataset for Model and runs hooks.
     def save
       run_hooks(:before_save)
       if @new
         run_hooks(:before_create)
         iid = model.dataset.insert(@values)
         # if we have a regular primary key and it's not set in @values,
         # we assume it's the last inserted id
         if (pk = primary_key) && !(Array === pk) && [EMAIL PROTECTED]
           @values[pk] = iid
         end
         if pk
           @this = nil # remove memoized this dataset
           refresh unless opts[:disable_auto_refresh]
         end
         @new = false
         run_hooks(:after_create)
       else
         run_hooks(:before_update)
         this.update(@values)
         run_hooks(:after_update)
       end
       run_hooks(:after_save)
       self
     end
   end
end

I don't know if you want to "litter" the code with this style of  
"unless opts[:something]", but it is one way to skin this cat. In the  
meantime I have monkey-patched my copy to do exactly this. It appears  
to work okay and has improved my application performance by about 6%  
(heavy inserts and updates where I cache the table's primary key for  
future updates and joins).

If you'd like me to provide this as a patch and a spec, let me know  
and I'll be happy to whip up a spec for it.

And if I haven't said it before, thanks for creating Sequel. It's is  
*so much* easier to hack this codebase than ActiveRecord!

cr

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to