views:

118

answers:

6

I have a query that is taking a lot longer then usual, and I cannot tell if it is stuck.

The query is something like this:

INSERT XXXXXX WITH (TABLOCK)
SELECT * FROM YYYYYY with (NOLOCK)
WHERE ZZZZZZZZ = 1

This will insert hundreds of millions of rows. I have an index on ZZZZZZZZ.

There are no blocking sessions. When I check sys.dm_exec_requests, it shows that the last wait type is PAGEIOLATCH_SH I'm not sure what this means, except that it has something to do with I/O.

sys.dm_exec_sessions shows the status is RUNNING, but sp_who2 shows it as SUSPENDED.

I tried to see if the table is growing, but when I call sp_spaceused XXXXXX, I keep getting the same values.

What else can I do?

UPDATE:

With the help of the answers below, I have found that there is an I/O issue, and that my query is resulting in an average of about 600 records being inserted per minute).

What is my next step?

What can I do before I start to assume that my disk is going bad?

+3  A: 

If you try the following

select * from sys.dm_os_waiting_tasks

does the resource address it's waiting on change at all?

select * 
into #t1
from sys.dm_os_wait_stats

waitfor delay '00:01'

select * 
into #t2
from sys.dm_os_wait_stats

SELECT #t2.wait_type, 
#t2.waiting_tasks_count - #t1.waiting_tasks_count as waiting_tasks_count, 
#t2.wait_time_ms- #t1.wait_time_ms as wait_time_ms, 
#t2.signal_wait_time_ms- #t1.signal_wait_time_ms as signal_wait_time_ms
FROM #t2  JOIN #t1 ON #t2.wait_type = #t1.wait_type
where #t2.wait_type not in ('CHECKPOINT_QUEUE','CHKPT','FT_IFTS_SCHEDULER_IDLE_WAIT',
'KSOURCE_WAKEUP',
'LAZYWRITER_SLEEP',
'LOGMGR_QUEUE',
'REQUEST_FOR_DEADLOCK_SEARCH',
'SQLTRACE_BUFFER_FLUSH' ,
'XE_DISPATCHER_WAIT',
'XE_TIMER_EVENT', 'WAITFOR')
order by wait_time_ms desc       
Martin Smith
It does seem to be changing periodically.
Gabriel McAdams
@Gabriel - If you check the values in `sys.dm_os_wait_stats` and then again a minute later what is taking the time? Is it all `PAGEIOLATCH`?
Martin Smith
If I execute select * from sys.dm_os_wait_stats, there are 485 records. I'm not sure what to look at.
Gabriel McAdams
@Gabriel - See edit.
Martin Smith
The top wait type is PAGEIOLATCH_SH (waiting_tasks_count = 3684, wait_time_ms = 94040, signal_wait_time_ms = 0). The others with any values are: SLEEP_TASK, BROKER_TO_FLUSH, and SOS_SCHEDULER_YIELD (small values in SOS_SCHEDULER_YIELD)
Gabriel McAdams
@Martin: What can I tell from this information?
Gabriel McAdams
@Gabriel - Nothing new. Just confirms that it is an I/O issue.
Martin Smith
@Martin: What can I do (now that I know its an I/O issue)?
Gabriel McAdams
A: 

Does the row count value of the table X property sheet show changes?

Beth
no. There has been no changed in the last few hours.
Gabriel McAdams
+2  A: 

Some thoughts that might help with the insert:

Are there any insert triggers on xxxxxx? Those could have a significant impact on a large insert operation.

Are there non-clustered indexes on xxxxxx that could be disabled during the load? That would also go a long way towards helping.

/* Before */
alter index YourIndex on xxxxxx disable
/* After */
alter index YourIndex on xxxxxx rebuild
Joe Stefanelli
There are no triggers on xxxxxxx. There is an index on xxxxx, but I am already doing what you suggest (disable, run, enable).
Gabriel McAdams
@Gabriel, for minimal logging on the insert, you need either a) a heap, or b) an **empty** clustered index. any other configuration will produce full logging.
Peter
@Peter, can you explain?
Gabriel McAdams
@Gabriel, seems you can get minimal logging w/ a non-empty clustered index, so long as the rows are ordered by the clustering key and you enable a trace flag. See here for more details: http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/03/23/minimal-logging-changes-in-sql-server-2008-part-2.aspx
Peter
more gory details: http://msdn.microsoft.com/en-us/library/ms190422.aspx. Also, the other biggie is that you can't be in full recovery model.
Peter
+1  A: 

Is the insert inside of a transaction? If it is, you could try to check the transaction details inside Sys.Dm_tran_database_Transactions. It shows the current number of entries writen to the transaction log along with some other health stats that should be changing over time:

SELECT * FROM Sys.Dm_tran_Database_Transactions

This is a link to the MSDN artical that explains the columns: MSDN Column documentation

Hope that helps

JaySilk84
It does show that there is a transaction on that particular database. It seems to be that of this query (although I didn't begin any transactions). the number of rows are growing slowly.
Gabriel McAdams
Sql by default will wrap everything in its own transaction implicitly if you didn't specify one explicitly and autocommit if it didn't error out
JaySilk84
+1  A: 

Ok, sounds like you may be in a DW-style environment, moving lots of data from one table to another. Assuming you are on SQL Server 2008, see this whitepaper:

The Data Loading Performance Guide

See the sections on minimal logging, and further down on partition switching.

It helps to read the whole paper through a few times, so you really grok what's going on beneath the covers, and why certain combinations of data + indexing work and others don't.

Partition switching makes minimal logging easy to achieve, since it gives you an empty target table, and allows new data to come on-line in an instant, once the load has finished. Might need enterprise edition, though.

Peter
A: 

DW Fact table?

http://books.google.com/books?id=eBacaL61sa4C&pg=PA268&lpg=PA268&dq=remove+index+when+updating+fact+table&source=bl&ots=MFB8HnmYRl&sig=w680N0GA3oSiJaS1mU_Z_WzW1VY&hl=en&ei=-EeOTKaQDtPyOeqZtLsK&sa=X&oi=book_result&ct=result&resnum=8&ved=0CD4Q6AEwBw#v=onepage&q&f=false

p268

adolf garlic
I'm not sure if this is an answer or a question... I read the passage from that book. What does it have to do with this?
Gabriel McAdams
If your table is in a DW, then it's a possible answer. i.e. remove the indexes during the update. If not, then it isn't :)
adolf garlic