Search code examples
sqlsql-serversql-server-2000sql-execution-plan

Why do I get "The log file for database 'tempdb' is full"


Let we have a table of payments having 35 columns with a primary key (autoinc bigint) and 3 non-clustered, non-unique indeces (each on one int column).

Among the table's columns we have two datetime fields:

  1. payment_date datetime NOT NULL

  2. edit_date datetime NULL

The table has about 1 200 000 rows. Only ~1000 of rows have edit_date column = null. 9000 of rows have edit_date not null and not equal to payment_date Others have edit_date=payment_date

When we run the following query 1:

select top 1 *
from payments
where edit_date is not null and (payment_date=edit_date or payment_date<>edit_date)
order by payment_date desc

enter image description here

server needs a couple of seconds to do it. But if we run query 2:

select top 1 *
from payments
where edit_date is not null
order by payment_date desc

enter image description here

the execution ends up with The log file for database 'tempdb' is full. Back up the transaction log for the database to free up some log space.

If we replace * with some certain column, see query 3

select top 1 payment_date
from payments
where edit_date is not null
order by payment_date desc

enter image description here

it also finishes in a couple of seconds.

Where is the magic?

EDIT I've changed query 1 so that it operates over exactly the same number of rows as the 2nd query. And still it returns in a second, while query 2 fills tempdb.

ANSWER I followed the advice to add an index, did this for both date fields - everything started working quick, as expected. Though, the question was - why in this exact situation sql server behave differently on similar queries (query 1 vs query 2); I wanted to understand the logic of the server optimization. I would agree if both queries did used tempdb similarly, but they didn't....

In the end I mark as the answer the first one, where I saw the must-be symptoms of my problem and the first, as well, thoughts on how to avoid this (i.e. indeces)


Solution

  • This is happening cause certain steps in an execution plan can trigger writes to tempdb in particular certain sorts and joins involving lots of data.

    Since you are sorting a table with a boat load of columns, SQL decides it would be crazy to perform the sort alone in temp db without the associated data. If it did that it would need to do a gazzilion inefficient bookmark lookups on the underlying table.

    Follow these rules:

    1. Try to select only the data you need
    2. Size tempdb appropriately, if you need to do crazy queries that sort a gazzilion rows, you better have an appropriately sized tempdb