cw84
cw84

Reputation: 2190

What is an unbounded query?

Is an unbounded query a query without a WHERE param = value statement?

Apologies for the simplicity of this one.

Upvotes: 9

Views: 5742

Answers (2)

BehrouzMoslem
BehrouzMoslem

Reputation: 9713

http://hibernatingrhinos.com/Products/EFProf/learn#UnboundedResultSet

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 instructs Entity Framework 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. Entity Framework does not provide a good way of paging through a collection when traversing the object graph. It is recommended that you would issue a 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.

Upvotes: 1

An unbounded query is one where the search criteria is not particularly specific, and is thus likely to return a very large result set. A query without a WHERE clause would certainly fall into this category, but let's consider for a moment some other possibilities. Let's say we have tables as follows:

CREATE TABLE SALES_DATA
  (ID_SALES_DATA      NUMBER PRIMARY KEY,
   TRANSACTION_DATE   DATE NOT NULL
   LOCATION           NUMBER NOT NULL,
   TOTAL_SALE_AMOUNT  NUMBER NOT NULL,
   ...etc...);

CREATE TABLE LOCATION
  (LOCATION  NUMBER PRIMARY KEY,
   DISTRICT  NUMBER NOT NULL,
   ...etc...);

Suppose that we want to pull in a specific transaction, and we know the ID of the sale:

SELECT * FROM SALES_DATA WHERE ID_SALES_DATA = <whatever>

In this case the query is bounded, and we can guarantee it's going to pull in either one or zero rows.

Another example of a bounded query, but with a large result set would be the one produced when the director of district 23 says "I want to see the total sales for each store in my district for every day last year", which would be something like

SELECT LOCATION, TRUNC(TRANSACTION_DATE), SUM(TOTAL_SALE_AMOUNT)
  FROM SALES_DATA S,
       LOCATION L
  WHERE S.TRANSACTION_DATE BETWEEN '01-JAN-2009' AND '31-DEC-2009' AND
        L.LOCATION = S.LOCATION AND
        L.DISTRICT = 23
  GROUP BY LOCATION,
           TRUNC(TRANSACTION_DATE)
  ORDER BY LOCATION,
           TRUNC(TRANSACTION_DATE)

In this case the query should return 365 (or fewer, if stores are not open every day) rows for each store in district 23. If there's 25 stores in the district it'll return 9125 rows or fewer.

On the other hand, let's say our VP of Sales wants some data. He/she/it isn't quite certain what's wanted, but he/she/it is pretty sure that whatever it is happened in the first six months of the year...not quite sure about which year...and not sure about the location, either - probably in district 23 (he/she/it has had a running feud with the individual who runs district 23 for the past 6 years, ever since that golf tournament where...well, never mind...but if a problem can be hung on the door of district 23's director so be it!)...and of course he/she/it wants all the details, and have it on his/her/its desk toot sweet! And thus we get a query that looks something like

SELECT L.DISTRICT, S.LOCATION, S.TRANSACTION_DATE,
       S.something, S.something_else, S.some_more_stuff
  FROM SALES_DATA S,
       LOCATIONS L
  WHERE EXTRACT(MONTH FROM S.TRANSACTION_DATE) <= 6 AND
        L.LOCATION = S.LOCATION
  ORDER BY L.DISTRICT,
           S.LOCATION

This is an example of an unbounded query. How many rows will it return? Good question - that depends on how business conditions were, how many location were open, how many days there were in February, etc.

Put more simply, if you can look at a query and have a pretty good idea of how many rows it's going to return (even though that number might be relatively large) the query is bounded. If you can't, it's unbounded.

Share and enjoy.

Upvotes: 10

Related Questions