Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's blocking "Select top 1 * from TableName with (nolock)" from returning a result?

I'm currently running the following statement

select * into adhoc..san_savedi from dps_san..savedi_record

It's taking a painfully long time and I'd like to see how far along it is so I ran this:

select count(*) from adhoc..san_savedi with (nolock)

That didn't return anything in a timely manner so for the heck of it I did this:

select top 1 * from adhoc..san_savedi with (nolock)

Even that seems to run indefinitely. I could understand if there are millions of records that the count(*) could take a long time, but I don't understand why selecting the top 1 record wouldn't come back pretty much immediately considering I specified nolock.

In the name of full disclosure, dps_san is a view that pulls from an odbc connection via linked server. I don't think that'd be affecting why I can't return the top row but just throwing it out there in case I'm wrong.

So I want to know what is keeping that statement from running?

EDIT:

As I mentioned above, yes dps_san..savedi_record is a view. Here's what it does:

select * from DPS_SAN..root.SAVEDI_RECORD

It's nothing more than an alias and does no grouping/sorting/etc so I don't think the problem lies here, but please enlighten me if I'm wrong about that.

like image 631
Brandon Moore Avatar asked Jun 08 '12 20:06

Brandon Moore


People also ask

What is select Nolock?

The WITH (NOLOCK) table hint is used to override the default transaction isolation level of the table or the tables within the view in a specific query, by allowing the user to retrieve the data without being affected by the locks, on the requested data, due to another process that is changing it.

What does the Nolock query hint do?

The NOLOCK hint allows SQL to read data from tables by ignoring any locks and therefore not get blocked by other processes. This can improve query performance by removing the blocks, but introduces the possibility of dirty reads.

What does select * from table mean?

An asterisk (" * ") can be used to specify that the query should return all columns of the queried tables. SELECT is the most complex statement in SQL, with optional keywords and clauses that include: The FROM clause, which indicates the table(s) to retrieve data from.

What does select top do in SQL?

The SQL SELECT TOP Clause The SELECT TOP clause is used to specify the number of records to return. The SELECT TOP clause is useful on large tables with thousands of records. Returning a large number of records can impact performance.


1 Answers

SELECT queries with NOLOCK don't actually take no locks, they still need a SCH-S (schema stability) lock on the table (and as it is a heap it will also take a hobt lock).

Additionally before the SELECT can even begin SQL Server must compile a plan for the statement, which also requires it to take a SCH-S lock out on the table.

As your long running transaction creates the table via SELECT ... INTO it holds an incompatible SCH-M lock on it until the statement completes.

You can verify this by looking in sys.dm_os_waiting_tasks whilst while during the period of blocking.

When I tried the following in one connection

BEGIN TRAN

SELECT *
INTO NewT
FROM master..spt_values

/*Remember to rollback/commit this later*/

And then executing (or just simply trying to view the estimated execution plan)

SELECT *
FROM NewT
WITH (NOLOCK)

in a second the reading query was blocked.

SELECT wait_type,
       resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id = <spid_of_waiting_task>

Shows the wait type is indeed SCH_S and the blocking resource SCH-M

wait_type        resource_description
---------------- -------------------------------------------------------------------------------------------------------------------------------
LCK_M_SCH_S      objectlock lockPartition=0 objid=461960722 subresource=FULL dbid=1 id=lock4a8a540 mode=Sch-M associatedObjectId=461960722
like image 178
Martin Smith Avatar answered Oct 03 '22 23:10

Martin Smith