upsert vs update vs insert

I’m trying to understand when to use insert/update/upsert. As I understand, upsert is a combination of insert and update. I tend to use upsert most often as I do not have to check whether an object is a new object or an existing object. I do not see a reason to use update or insert since upsert calls would work for these calls. Is there a reason I should not be using upsert and instead use the other two?

Answer

In general, there’s no real penalty for using upsert as opposed to insert and update. One notable limitation, however, is that upsert does not support generic SObject[] lists or generic SObject records. This also means you can’t take advantage of combining DML calls to reduce governor limit usage. For example, consider this code:

Account a = new Account(Name='Test');
insert a;
Contact c = new Contact(LastName='Test', AccountId=a.Id);
Opportunity o = new Opportunity(Name='Test', CloseDate=Date.today(), Amount=1000, StageName='Prospecting', AccountId=a.Id);
insert new SObject[] { c, o };

In this case, we created 3 records using just 2 DML statements of our allowed 150. However, with upsert, we can’t do this, and end up using 3 DML statements. For many cases, it doesn’t matter, but reducing DML usage can be important during unit tests that involve setting up a many different types of records. In a larger scenario, this could be significant, as you can combine up to ten different types of records in a single SObject list, saving up to 9 DML calls every time you use this technique.

Besides that, in the more general case, upsert is not self-documenting. By that, I mean that overusing upsert makes it harder to tell if it’s really an upsert, or always an insert, or always an update. You should only use upsert when it really is a situation where it may be an insert or update. Using upsert unnecessarily throws doubt at those that will have to maintain your code later. This is probably the most important consideration.

Edit: One additional consideration. I’ve benchmarked this before, and it uses roughly the same CPU time as deciding if you want to do an insert or update manually (e.g. writing an if statement with both insert and update branches). This means that if you know it’s an insert or update, you’ll shave off a few milliseconds by using the appropriate DML statement. Since we only have a limit of 150 DML statements, it doesn’t save much time, perhaps maybe a 1/3 of a second if you were near the limit, but it is a performance hit.

Attribution
Source : Link , Question Author : trescha , Answer Author : sfdcfox

Leave a Comment