开发者

How can I tell why my query is taking so long?

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?


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       


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


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


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜