I have a complex select query and a huge table.
I'm running this select
statement, meanwhile an Update
statement arrives and tries to update the table.
IMHO - update requires an exclusive lock - so the update statement will have to wait till the select command is finished.
Am I right ?
what can I do in order to: execute the complex
select
, and also let theupdate
command run (currently I don't care about dirty data)
When you run the two statements concurrently (a SELECT and an UPDATE) the actual behavior will be basically random. This is because neither of the operations is instantaneous. To simplify, consider your table a list and SELECT is traversing this list, looking at one row at a time. UPDATE is also trying to update one or more rows. When the UPDATE is trying to update a row behind the SELECT then nothing happens (no blocking) because the SELECT has already progressed past the UPDATE point. If the UPDATE is trying to update the row at which SELECT is looking right now then the UPDATE will have to wait for SELECT to move on, which will happen very very very fast and the UPDATE will unblock and succeed, while the SELECT is moving ahead. But if the UPDATE is updating a row ahead of the SELECT then the update will succeed and, later, SELECT will eventually reach exactly this row and will stop, blocked. Now SELECT has to wait until the transaction that did the UPDATE commits.
This is the simplified story. The real life is much more complicated. The SELECT can have multiple read points (parallel plans). Both the SELECT and the UPDATE are subject to choosing an access path, meaning use one or more secondary indexes to locate the rows. Complex queries may contain operators that cause multiple lookups into a table (eg. joins). Both the SELECT and the UPDATE can do bookmark lookups to fetch BLOB data, which changes significantly the locking behavior. Cardinality estimation may cause the SELECT to run at a high granularity lock mode (eg. table level Shared lock). The UPDATE can trigger lock escalation, and the escalation can fail or succeed. Choosing different access paths can lead to deadlock. False lock contention can occur due to hash collisions. There are just about one myriad variables that have a say in this. And I didn't even mention higher isolation levels (repeatable read, serializable).
Perhaps you should use SNAPSHOT isolation and stop worrying about this issue?
Yes - to a degree.
How long a
SELECT
holds on to a shared lock is depending on the isolation level of the transaction:READ UNCOMMITTED
- no shared lock is acquired at all -UPDATE
is not blockedREAD COMMITTED
- shared lock is acquired just for the duration of reading the data -UPDATE
might be blocked for a very short period of timeREPEATABLE READ
andSERIALIZABLE
- shared lock is acquired and held on to until the end of the transaction -UPDATE
is blocked until theSELECT
transaction endsTechnically, the
UPDATE
statement first gets anUPDATE
lock - which is compatible with a shared lock (as used by theSELECT
) - for the duration of the time while it's reading the current values of the rows to be updated.Once that's done, the
Update
lock is escalated to an exclusive lock for the new data to be written to the table.