Feel my pain…

Update: Still slow…

Update: Check out how fast Campaign Membership inserts are…

Two reasons–no Apex is running on this table, and they’ve optimized Campaign Member inserts heavily because it’s a very high volume object.
Update: First screenshot was from a Contacts insert, second from an Opportunity Insert.
Update: In the comments I clarify that I knew from the start that slowness is due to the Apex triggers I’ve written that are running on my inserts. So the pain is self-inflicted, a combination of Apex code and batch size=100 because of heap and script statement limit problems.

December 17th, 2007 at 1:16 pm
Hey Steve, this is the api dev manager. What objects are the first two screenshots inserting on? We haven’t had any reports of slow api access today…
Thanks…
December 17th, 2007 at 5:18 pm
Hey Peter. I think it’s all related to the Apex triggers I have running. The api is it’s normal blazing speed on exports and inserts to tables where I’m not running my Apex triggers. I guess throttled performance is the trade-off with complex triggers! And that’s the problem with letting other people write server-side code–it makes you look bad when it’s not your fault!
December 17th, 2007 at 5:45 pm
What are you doing in the triggers?
December 17th, 2007 at 8:03 pm
With the Contact insert, I’m traversing to a custom object via a lookup and then updating Address fields on that object to match what’s on the contact. Then I’m finding all Contacts also related to that custom object and cascading the address updates down to them.
With the Opportunity insert I’m creating a contact role for a Contact whose Id I’m passing in on the Opportunity. Then I’m doing a rollup of closed one Opp amounts for that Contact.
December 18th, 2007 at 7:09 am
Steve; I tend to build APEX triggers so that they only fire when one object is being updated/inserted/deleted. This way bulk inserts and updates complete much faster and only updated/inserted objects via the UI are effected by the triggers.
The big downside, of course, is that this assumes that you don’t want to run Apex Code against bulk inserted objects.
GlennW
December 18th, 2007 at 8:00 am
That is remarkable — so far, I’ve thought of Apex as *speeding up* my Salesforce experience, because I’ve used it to replace some slow s-control code or repetitive human tasks. But it looks like we’ll have to pay extra attention to profiling and efficiency as we use more Apex.
I too have written most triggers to fire only on a single update, but there is a big incentive to use this stuff in bulk operations like this as well. Even if it takes a couple hours, that is a lot less time than it would take me to arrange all those background updates in a spreadsheet and upload them manually.
December 18th, 2007 at 1:38 pm
Yeah, we’re with Evan on this one. The triggers that are firing here are absolutely ones that we want to have happen on import, and that save us a ton of time on pre-processing the data.
We’re just hoping to find ways to speed things up without getting rid of the functionality.
Waiting a couple of hours one time probably isn’t so bad. The problem is that imports often have to be repeated when you find you didn’t get everything perfect the first time. Ask Steve how much he enjoyed waiting a couple of hours the 3rd or 4th time.
December 18th, 2007 at 2:57 pm
Right now the trick is to get the bulk processing apex so that it functions at the 200 batch size, so that if the customer does inserts from Glenn’s DemandTools or imports from the Lead Import Wizard, they won’t bonk. DemandTools will let us do small batches, but would love to not have to train the user that small batch sizes are the only ones that work.