Unbounded result set

An unbounded result set is where a query is performed and does not explicitly limit the number of returned results from a query. Usually, this means that the application assumes that a query will always return only a few records. That works well in development and in testing, but it is a time bomb waiting to explode in production.

The query may suddenly start returning thousands upon thousands of rows, and in some cases, it may return millions of rows. This leads to more load on the database server, the application server, and the network. In many cases, it can grind the entire system to a halt, usually ending with the application servers crashing with out of memory errors.

Here is one example of a query that will trigger the unbounded result set warning:

var query = from post in blogDataContext.Posts
where post.Category == "Performance"
select post;

If the performance category has many posts, we are going to load all of them, which is probably not what was intended. This can be fixed fairly easily by using pagination by utilizing the Take() method:

var query = (from post in blogDataContext.Posts            
where post.Category == "Performance"
select post)
.Take(15);

Now we are assured that we only need to handle a predictable, small result set, and if we need to work with all of them, we can page through the records as needed. Paging is implemented using the Skip() method, which instruct Linq to Sql to skip (at the database level) N number of records before taking the next page.

But there is another common occurrence of the unbounded result set problem from directly traversing the object graph, as in the following example:

var post = postRepository.Get(id);
foreach(var comment in post.Comments)
{
// do something interesting with the comment
}

Here, again, we are loading the entire set without regard for how big the result set may be. Linq to Sql does not provides a good way of paging through a collection when traversing the object graph. It is recommended that you would issue an separate and explicit query for the contents of the collection, which will allow you to page through that collection without loading too much data into memory.

Last update: 11/13/2009 7:26:54 AM