We're using a SQL Server 2005 database (no row versioning) with a huge select statement, and we're seeing it block other statements from running (seen using sp_who2
). I didn't realise SELECT statements could cause blocking - is there anything I can do to mitigate this?
相关问题
- sql execution latency when assign to a variable
- What is the best way to cache a table from a (SQL)
- php PDO::FETCH_ASSOC doesnt detect select after ba
- Faster loop: foreach vs some (performance of jsper
- Bulk update SQL Server C#
相关文章
- Entity Framework 4.3.1 failing to create (/open) a
- Code for inserting data into SQL Server database u
- DOM penalty of using html attributes
- Which is faster, pointer access or reference acces
- Delete Every Alternate Row in SQL
- Linux based PHP install connecting to MsSQL Server
- SQL Azure Reset autoincrement
- Django is sooo slow? errno 32 broken pipe? dcramer
You might also get deadlocks:
"deadlocks involving only one table" http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/01/reproducing-deadlocks-involving-only-one-table.aspx
and or incorrect results:
"Selects under READ COMMITTED and REPEATABLE READ may return incorrect results."
http://www2.sqlblog.com/blogs/alexander_kuznetsov/archive/2009/04/10/selects-under-read-committed-and-repeatable-read-may-return-incorrect-results.aspx
You could set the transaction level to Read Uncommitted
To perform dirty reads you can either:
or
remember that you have to write WITH (NOLOCK) after every table you want to dirty read
From documentation:
A
shared lock
is compatible with another shared lock or an update lock, but not with an exlusive lock.That means that your
SELECT
queries will blockUPDATE
andINSERT
queries and vice versa.A
SELECT
query will place a temporary shared lock when it reads a block of values from the table, and remove it when it done reading.For the time the lock exists, you will not be able to do anything with the data in the locked area.
Two
SELECT
queries will never block each other (unless they areSELECT FOR UPDATE
)You can enable
SNAPSHOT
isolation level on your database and use it, but note that it will not preventUPDATE
queries from being locked bySELECT
queries (which seems to be your case).It, though, will prevent
SELECT
queries from being locked byUPDATE
.Also note that
SQL Server
, unlikeOracle
, uses lock manager and keeps it locks in an in-memory linked list.That means that under heavy load, the mere fact of placing and removing a lock may be slow, since the linked list should itself be locked by the transaction thread.
SELECT can block updates. A properly designed data model and query will only cause minimal blocking and not be an issue. The 'usual' WITH NOLOCK hint is almost always the wrong answer. The proper answer is to tune your query so it does not scan huge tables.
If the query is untunable then you should first consider SNAPSHOT ISOLATION level, second you should consider using DATABASE SNAPSHOTS and last option should be DIRTY READS (and is better to change the isolation level rather than using the NOLOCK HINT). Note that dirty reads, as the name clearly states, will return inconsistent data (eg. your total sheet may be unbalanced).