Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it considered bad practice to use cursors in SQL Server?

I knew of some performance reasons back in the SQL 7 days, but do the same issues still exist in SQL Server 2005? If I have a resultset in a stored procedure that I want to act upon individually, are cursors still a bad choice? If so, why?

like image 205
Kilhoffer Avatar asked Sep 12 '08 01:09

Kilhoffer


People also ask

Why are cursors bad in SQL Server?

Cursors could be used in some applications for serialized operations as shown in example above, but generally they should be avoided because they bring a negative impact on performance, especially when operating on a large sets of data.

What is cursor disadvantage?

Disadvantages of using Cursor: So occupies more resources and temporary storage. Each time when a row is fetched from the cursor it may result in a network round trip. This uses much more network bandwidth than the execution of a single SQL statement like SELECT or DELETE etc that makes only one round trip.


2 Answers

Because cursors take up memory and create locks.

What you are really doing is attempting to force set-based technology into non-set based functionality. And, in all fairness, I should point out that cursors do have a use, but they are frowned upon because many folks who are not used to using set-based solutions use cursors instead of figuring out the set-based solution.

But, when you open a cursor, you are basically loading those rows into memory and locking them, creating potential blocks. Then, as you cycle through the cursor, you are making changes to other tables and still keeping all of the memory and locks of the cursor open.

All of which has the potential to cause performance issues for other users.

So, as a general rule, cursors are frowned upon. Especially if that's the first solution arrived at in solving a problem.

like image 163
Josef Avatar answered Sep 19 '22 19:09

Josef


The above comments about SQL being a set-based environment are all true. However there are times when row-by-row operations are useful. Consider a combination of metadata and dynamic-sql.

As a very simple example, say I have 100+ records in a table that define the names of tables that I want to copy/truncate/whatever. Which is best? Hardcoding the SQL to do what I need to? Or iterate through this resultset and use dynamic-SQL (sp_executesql) to perform the operations?

There is no way to achieve the above objective using set-based SQL.

So, to use cursors or a while loop (pseudo-cursors)?

SQL Cursors are fine as long as you use the correct options:

INSENSITIVE will make a temporary copy of your result set (saving you from having to do this yourself for your pseudo-cursor).

READ_ONLY will make sure no locks are held on the underlying result set. Changes in the underlying result set will be reflected in subsequent fetches (same as if getting TOP 1 from your pseudo-cursor).

FAST_FORWARD will create an optimised forward-only, read-only cursor.

Read about the available options before ruling all cursors as evil.

like image 36
Daniel P Avatar answered Sep 17 '22 19:09

Daniel P