Think you know how to write UPDATE statement? Think again.

When I was a kid, my mom used to read me UPDATE queries every night before I went to sleep. I heared many stories about updating objects to database where most of them were the same old:


UPDATE [ Table ] SET Field1 = Value1, Field2 = Value2, . . . WHERE PRIMARYKEY = TheKey

So, I grew up with the same ideas on how to update objects in tables as other kids do. All the UPDATE queries involved taking all the fields and the update stored procedures used to have all the properties of the objects. If you are using some Code Generators (e.g. Code Smith) and generating data access layer codes and stored procedures for objects, you will see almost all the code generators and ORM tools generate UPDATE statments with all the fields in the SET block. Let me show you with an example how evil this idea is.

Imagine a table like this:


CREATE TABLE [ dbo ] . [ ChannelSubscribedByUser ] ( [ ID ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL , [ UserId ] [ int ] NOT NULL , [ ChannelId ] [ int ] NOT NULL , [ ReadRSSItemIDs ] [ image ] NOT NULL , CONSTRAINT [ PK_ChannelSubscribedByUser ] PRIMARY KEY CLUSTERED ( [ UserId ] ASC , [ ChannelId ] ASC )

This is a table from Pageflakes database. In this table, we store all the RSS feeds user has read from a particular RSS channel. UserId is a foreign key to User table and ChannelID is a foreign key to Channel table. Pretty straight forward. We had a harmless update stored procedure generated using Code Smith using the famous .NET Tiers template.


ALTER PROCEDURE [ dbo ] . [ prcChannelSubscribedByUserUpdate ] @ID int , @ChannelId int , @ReadRSSItemIDs image , @UserId int AS UPDATE dbo. [ ChannelSubscribedByUser ] SET [ ChannelId ] = @ChannelId , [ ReadRSSItemIDs ] = @ReadRSSItemIDs , [ UserId ] = @UserId WHERE [ ID ] = @ID SELECT [ ID ] , [ UserId ] , [ ChannelId ] , [ ReadRSSItemIDs ] FROM dbo. [ ChannelSubscribedByUser ] WHERE [ ID ] = @ID

Look at the query plan and see how horrible it really is:

 

 

There are 2 Clustered Index Seeks, one Table Spool (very expensive), 2 Nested Loops, 1 Assert, 1 Clustered Index Seek. If you look at the IO Statistics, you can see how truly evil this query is:

Table 'RSSChannel'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PageFlakesUser'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ChannelSubscribedByUser'. Scan count 1, logical reads 15, physical reads 0, read-ahead reads 0, lob logical reads 3, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

It is making SQL Server go to the tables which are refered as foreign key during a single row update!

Generally when we update a row in a table which represents an object, we rarely change the value of the fields which are foreign keys to other tables and has index on them. Most of the time, the updates are on the fields which contain properties, not relations. For example, 99% of the cases, you will update properties of an Employee object like FirstName, LastName, Age etc. 1% case you will modify the CompanyID (because s/he was fired) which is a foreign key to Company Table. But if you go to your database and see the stored procedure which updates the Employee object, you will see this:


UPDATE Employee SET FirstName = @FirstName , LastName = @LastName , CompanyID = @CompanyID WHERE EmployeeID = @EmployeeID

Don't be ashamed. I know we all have queries like this every where.

If you remove those unwanted fields which generally have Foreign Key and Index on them, you can gain significant performance improvement. When I just change the UPDATE statement to this:


UPDATE dbo. [ ChannelSubscribedByUser ] SET [ ReadRSSItemIDs ] = @ReadRSSItemIDs , WHERE [ ID ] = @ID

See the query plan:

There's just one Clustered Index Update. No Table Spool, no Clustered Index seeks, no nested loops, no asserts. The IO statistics shows how significant the improvement really is:

Table 'ChannelSubscribedByUser'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 3, lob physical reads 0, lob read-ahead reads 0.

There's just one update and nothing else. Also the number of Logical Reads is 6 compared to 15.

So, you thought you knew how to write UPDATE statements? Think again.

Published Sat, Jan 20 2007 17:47 by omar
Filed under:

Comments

# re: Think you know how to write UPDATE statement? Think again.

Saturday, January 20, 2007 1:03 PM by Mehfuz

This is indeed , some to think about. One thing I would like to add :-

When SQL update statement is consists of foreign key modification, the extra execution path is generated because of validating the foreign key, and finally combining it up to the main table.

But, if we remove the foreign key, the extra branch is no longer generated. Now, if data-access layer ensures 100% accuracy of passing valid keys, then I guess, it is possible remove the unnecessary foreign key references that cause the SQL server do some extra logical operation.

Happy coding!

# re: Think you know how to write UPDATE statement? Think again.

Thursday, January 25, 2007 12:50 PM by Anders Haahr

Nice tip, Omar.

In one of my recent projects where I could not use stored procedures I did it clientside like you can see in the code I've pasted below.

I keep a dictionary of the dirty fields on my entity and use it to generate the field = @value pairs in the update command.

How could one provide the same flexibility in T-SQL without creating tons of stored procedures?

Btw. congratulations for being editor's choice on codeproject :-)

internal SqlCommand GetUpdateCommand()

       {

           SqlCommand cmd = new SqlCommand();

           cmd.Connection = GetConnection();

           StringBuilder sbValues = new StringBuilder();

           // in case of update we need the id which is not in the changedFields dic

           cmd.Parameters.AddWithValue("@" + PrimaryIdColumnName, ID);

           // loop through the changeDictionary and build strings to use in the SQL string.

           // also add parameters to the sqlcommand

           foreach (KeyValuePair<string, Object> kvp in changeDictionary)

           {

               sbValues.Append(kvp.Key + " = @" + kvp.Key + ", ");

               cmd.Parameters.AddWithValue("@" + kvp.Key, kvp.Value);

           }

           cmd.CommandText =

               string.Format(

                   "UPDATE {0} SET {1} Edited = GETDATE() WHERE {2} = @{2}; SELECT * FROM {0} WHERE {2} = @{2}",

                   TableName, sbValues.ToString(), PrimaryIdColumnName);

           return cmd;

       }

# re: Think you know how to write UPDATE statement? Think again.

Friday, January 26, 2007 8:29 AM by Omar

There's an overhead of change dictionary. For each object, there's one dictionary. So, it actually takes 3x more memory than simple objects.

Instead of dictionary, you can maintain an array of boolean like:

if( obj.IsChanged[0] )

{

Update field 1

}

# 英语阅读推荐:你真的懂UPDATE语句吗

Thursday, February 08, 2007 8:46 AM by Cat Chen

RandomClippings栏目已经有一段时间没有更新了,主要是因为一直没能挑选到适合的文章推荐(有可能是因为这段时间我读英文文章少了,哈哈),这次一定要好好补上,推荐两篇好文章给大家。

你真的...

# 英语阅读推荐:你真的懂UPDATE语句吗 &amp; 当有layout之时

Thursday, February 08, 2007 9:44 AM by cnblogs.com

Random Clippings 栏目已经有一段时间没有更新了,主要是因为一直没能挑选到适合的文章推荐(有可能是因为这段时间我读英文文章少了,哈哈),这次一定要好好补上,推荐两篇好文章给大家。 你真的懂UPDATE语句吗

# re: Think you know how to write UPDATE statement? Think again.

Thursday, March 01, 2007 5:47 AM by Farrukh Shahzad

Because of this foreign key reads/writes till mysql 4.0 foreign keys were not introduced.

What is your idea about maintaining data consistency by database layer or by business layer of an application?

As an application developer I know my foreign tables and primary tables so while coding the business logic i can take care of the foreign key issues.

Regards,

Farrukh

# re: Think you know how to write UPDATE statement? Think again.

Thursday, May 17, 2007 6:42 PM by ewa sonnet

I'm no good my love and have fun with I'm no good who else love extention green world Thanks you Buy zej.bravehost.com/ewa-sonnet.html super children Glad to see you time I'm no good Buy Order this come to you who else Good work! ewa sonnet

# re: Think you know how to write UPDATE statement? Think again.

Tuesday, May 29, 2007 3:24 AM by Moshiur Murshed

Interesting....

My Idea was to introduce more Foreign keys in a table so that I can enforce referantial intigrity...

I have to think again......

Thanx for sharing.

# re: Think you know how to write UPDATE statement? Think again.

Saturday, August 18, 2007 1:03 PM by Anabolik forever,Anabolikoid

Hi good for you but visit this <a href=" proviron.tabletdiet.org ">buy online ephedrine product</a>

# re: Think you know how to write UPDATE statement? Think again.

Monday, August 20, 2007 6:00 AM by DietMan1,Diet

Helo, it is very interesting site. If You want you can visit mine. <a href=" atken-diet.simplediet.org "> low weight loss chloresterol diet</a> I have make it myself. There you can find all about healthy food.

# re: Think you know how to write UPDATE statement? Think again.

Thursday, August 23, 2007 8:18 PM by LawyerForYou,LawyerForYou

Helo, it is very interesting site. If You want you can visit mine. <a href=" wv-regional-jail.hostsy.us "> murphys law law</a> I have make it myself. There you can find all about law, lawyers, judges etc...

# re: Think you know how to write UPDATE statement? Think again.

Thursday, August 23, 2007 8:18 PM by LawyerForYou,LawyerForYou

Helo, it is very interesting site. If You want you can visit mine. <a href=" wv-regional-jail.hostsy.us "> murphys law law</a> I have make it myself. There you can find all about law, lawyers, judges etc...

# re: Think you know how to write UPDATE statement? Think again.

Sunday, August 26, 2007 8:45 PM by AirfareForYou,AirfareForYou

Helo, it is very interesting site. If You want you can visit mine. <a href=" hawaii-airline.usaspace.biz "> ted buy airline</a> I have make it myself. There you can find all about airlines, cheap airfares etc...

# re: Think you know how to write UPDATE statement? Think again.

Sunday, August 26, 2007 8:46 PM by AirfareForYou,AirfareForYou

Helo, it is very interesting site. If You want you can visit mine. <a href=" hawaii-airline.usaspace.biz "> ted buy airline</a> I have make it myself. There you can find all about airlines, cheap airfares etc...

# re: Think you know how to write UPDATE statement? Think again.

Thursday, August 30, 2007 7:00 AM by AllForYou123,AllForYou123

Helo, it is very interesting site. If You want you can visit mine. <a href=" mail-rcn-web.usgol.info "> sook yin lee</a> I have make it myself. There you can find all about  sook yin lee etc...

# re: Think you know how to write UPDATE statement? Think again.

Tuesday, October 02, 2007 12:47 PM by caveman_dick

This is where decent a decent OR mapper like llblgen pro will be your best friend, it dynamically creates update statements based on the fields you actually change!

# re: Think you know how to write UPDATE statement? Think again.

Friday, October 12, 2007 3:25 AM by lazynerd

Omar, way to go... wish I could be ever like you. At least will try to make my son like you. Thats what I can say.

# re: Think you know how to write UPDATE statement? Think again.

Wednesday, October 24, 2007 6:56 PM by ford1123,ford12331

All about ford cars and parts <a href=" http://ford-seattle.uertr.com ">albany ford new york</a>albany ford new york

# 10 cool web development related articles in 2007

Wednesday, November 21, 2007 5:04 AM by 杨正祎

非原创,来源网络。感谢原作者奉献如此精彩文章。原文地址:

www.cnblogs.com/.../922901.html 10...

# re: Think you know how to write UPDATE statement? Think again.

Thursday, November 22, 2007 5:31 AM by Hemant Gupta

Hi,

great article and i would like to say that i am a great fan of your, i have one eye on your blog all the time. regarding the update article i agree with your but can you shed some light how really do we handle a update statement when we are updating a form with 1-20 feilds. cause way i see it doing it with lot of if else will also have its over head. won't it.  

# re: Think you know how to write UPDATE statement? Think again.

Friday, March 28, 2008 10:27 AM by Tahajjud Miah

Slms Omar,

I must say I am impressed with your knowledge! From what I understand, you are advocating updates without references to foreign keys - i assume you would have a separate procedure to deal with such updates because they are called very infrequently and hence can take the hit?

or are you advocating no keys in the data layer and offloading that to the application layer like some extremely large databases?

wa'slm,

T

# re: Think you know how to write UPDATE statement? Think again.

Saturday, January 24, 2009 5:32 AM by chetan

i am using

string sql = "UPDATE Payment_Getway SET paymentstatus = '" + status + "' WHERE CAST([ID] AS VARCHAR(20)) = '" + pgid + "'";

Execute_Query(sql);

update statement is not executed.

# re: Think you know how to write UPDATE statement? Think again.

Wednesday, June 10, 2009 9:54 PM by gas powered scooters

Help me to find rock gas powered scooters

www.world66.com/.../gas_powered_scoote

# re: Think you know how to write UPDATE statement? Think again.

Thursday, June 11, 2009 4:04 AM by paris hilton sex tape

Nice site about watch paris hilton sex tape

# re: Think you know how to write UPDATE statement? Think again.

Thursday, June 11, 2009 8:01 PM by r kelly sex tape

Now inside the r kelly sex tape now www.youtube.com/.../rkellytapesex

# re: Think you know how to write UPDATE statement? Think again.

Friday, June 12, 2009 2:21 AM by kristin davis sex tape

Only with guarantee best kristin davis sex tape

Leave a Comment

(required) 
(required) 
(optional)
(required)