Author Archive: Gail

Execution plans, estimated vs actual

This is the second post on execution plans. I’m going to briefly discuss estimated execution plans and actual execution plans, the differences between them and when you would want to use which.

First however, a bit on query execution, just so that I know everyone’s on the same page.

When a query is submitted to SQL Server (and for simplicity I’m going to assume it’s a straight select statement not a procedure) the query is parsed, then bound to the underlying objects(tables, views, functions, etc). Once the binding is complete, the query passes to the query optimiser. The optimiser produces one or more suitable execution plans for the query (more on that in a later post). The query is then passed into the query execution engine, which does the memory grants, picks a parallelism option, if necessary and executes the various query operations.

Estimated execution plans

When an estimated execution plan is requested for a query, the query goes through the parsing, binding and optimisation phases, but does not get executed.

(more…)

Back in the GM chair

This last sunday saw me taking back the GM chair for the group that I play with. For the past year we’ve been playing my friend Phillip’s Per-rune game. (details and an in-character journal on my web site)

My campaign is a modern day supernatural game, a bit like Buffy, but darker. It’s set in the historical city of Oxford, in England, in the year 2002. More details are available on the campaign web site. The pages aren’t finished, there’s a lot of links that go no where.

All in all, the game went off without a hitch. Lots of admin-type stuff to start, reminders of clues, shopping, etc, etc but less than I expected.

Now let’s see if the characters can unravel the mysteries of a haunted house, and if they can survive to tell the tale.

I’ll probably comment here occationally on on significant bits of the campaign as they happen.

Structure of an execution plan

So, this is the first part of the series on how to read an execution plan. In this post, I’m going to give a high-level overview of how the execution plan looks and how, in general, to read it.

For the purposes of this and other posts in this series, all screenshots will be from SQL Management Studio (the 2005 GUI) and all comments on features will refer to that tool. Query Analyser, from SQL 2000, is very similar. For other querying tools, your mileage may vary.

Here’s a very simple execution plan. The query that produced this plan is just a join of three tables in the AdventureWorks database on SQL 2005.

Execution plan

(more…)

PASS 2007

Well, looks like I’m going to Denver for the Pass 2007 summit after all. I wasn’t sure I’d be going this year.

As usual there are more fantastic looking sessions that I could possibly manage to go to. In one slot on the Wednesday, I’d need to be in four places at the same time to attend everything I want to see.

(more…)

Reading Execution plans

One of the more common questions I get from colleagues is on how to read the execution plan that SQL produces. At first I found it quite a hard question to answer as no one really taught me how to read them. When I started with performance tuning I got a bit thrown in the deep end.

This is going to be the first in a series, maybe short, maybe long, on reading SQL’s execution plans. I’m going to go into the overall structure of a plan; the differences between the actual and the estimated plans, and how to obtain both; and some of the more common query operators and how they affect query performance.

If you have any specific questions that you’d like answering regarding execution plans, please post a comment here. Otherwise I’m going to ramble on a bit touching on things that I feel are important and relevant and maybe missing things that you would like to know.

Current articles in this series, in order of writing, are

  1. Structure of an execution plan
  2. Execution plans, estimated vs actual
  3. Execution plans from Profiler
  4. A basic execution plan
  5. Execution plan operations – scans and seeks
  6. Execution plan operations – joins
  7. Execution plan operations – aggregate
  8. Execution plan operations – misc
  9. Execution plans – important properties
  10. Execution plan – more properties
  11. An example execution plan

There is more to come.

DateTime Conversions

Or ‘That’s not the date I wanted?

Date time conversions are among the trickiest of conversions in SQL, and the most likely to cause unexpected errors. Mostly, this is because of the variety of formats that dates, when expressed as strings, can be written with. Let’s start with a simple example.

SELECT CAST('20/05/2007' as DATETIME)

Should work?

Msg 242, Level 16, State 3, Line 1
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.

(more…)

Implicit conversions

Or ‘How to slow down a query without apparent reason’

I’ve discussed functions in where clauses before and shown how they can prevent index usage and slow down queries. I’ve also discussed data type conversions and shown that SQL Server sometimes does the conversions in places not expected. There’s a nice little gotcha that results from the combination of these two. Let’s take a look at a simple example.

Which of the following queries will run slower? (sample code at the end)

Select ID from TestingConversion where Code = 'AAA'
Select ID from TestingConversion where Code = N'AAA'

(more…)

Order of execution

Or “Which where runs when?

There seems to be a lot of misunderstanding about what order conditions within a where clause are executed. In two days I heard from three different places comments about what order conditions must be put in the where clause.

The simple truth is that is doesn’t matter. Let’s look at a very simple example. (Sample code at the end as always)

SELECT * from tblTestWhereOrder WHERE A=1 and B=2 and C is not null

(more…)

Functions in a where clause

Or ‘How to really slow a query down without trying’

Here’s a query that looks innocent enough. Table structure and sample data are at the end of the post.

-- returns 5 out of 5000 rows
SELECT InsertDate FROM TestingFunction WHERE LEFT(Code,1)='AA'

Knowing that there’s an index on the column code, the optimiser might be expected to use an index seek to satisfy the query. However, the execution plan shows an index scan. Why?

(more…)