Monday, June 29, 2009

Using JOIN, NOLOCK, and Table (Index) Hints Together

[Update - 2013-12-23: As Sven Treffinger has pointed out in the comments, this post should include a warning about using NOLOCK. Here are a couple examples of the many articles on-line about the evils of NOLOCK:


So, proceed only after you understand the risks of NOLOCK.]

Using JOIN, NOLOCK, or table hints by themselves is straightforward, but what if you need to use them all at once? What's the order?

I tried and failed with a number of different permutations. I finally figured out that the NOLOCK has an implied WITH*. That brought me to the solution.
SELECT ...
FROM xx AS x WITH (NOLOCK)
JOIN yy AS y WITH (NOLOCK, INDEX (yIdx))
ON x.col = y.col
* I always write NOLOCKs using the the WITH and "()", but I didn't write this query originally.

Here is an example that you can run:
IF OBJECT_ID('tempdb..#t1') IS NOT NULL
DROP TABLE #t1
IF OBJECT_ID('tempdb..#t2') IS NOT NULL
DROP TABLE #t2
GO
CREATE TABLE #t1 (ColID int IDENTITY, Col2 int)
CREATE TABLE #t2 (ColID int IDENTITY, Col2 int)
GO
CREATE INDEX t1Col2 ON #t2 (Col2)
GO
INSERT INTO #t1 (Col2) VALUES (1)
INSERT INTO #t1 (Col2) VALUES (2)
INSERT INTO #t2 (Col2) VALUES (3)
INSERT INTO #t2 (Col2) VALUES (4)
GO
SELECT t1.Col2, t2.Col2
FROM #t1 AS t1 WITH (NOLOCK)
JOIN #t2 AS t2 WITH (NOLOCK, INDEX (t1Col2))
ON t1.ColID = t2.ColID


Col2 Col2
---- ----
   1    3
   2    4

5 comments:

  1. Anonymous7:28 AM

    awesome. many thanks for this information

    ReplyDelete
  2. yes, go ahead and blindly use with(nolock) without knowing anything about how that blackbox of a dbms works. Who ever wanted to have results of a query where you dont have to question the validity of the returned data anyway.

    Guys, don't use query hints while you don't even have a good grasp of the pritty basic tsql syntax. You are going to shoot yourself in the foot so hard your leg is going to be missing. Especially on with(nolock). Just google with(nolock) and read up on it....

    ReplyDelete
  3. Sven, I completely understand that there are issues with NOLOCK and table hints. In this particular case, I was using the hint to test the performance difference between two different indexes. Once I had proven which one was the best index design, I dropped the second index and removed the hint.

    And NOLOCK? I was working in an organization where NOLOCK was expected for every reporting query. That was a battle that had been fought and lost before I got there.

    ReplyDelete
    Replies
    1. I worded it a bit harshly, the comment of some random guy going "oh great awesome" kind drove me into a mild depression. So, i'd like to appologize for that, the wording.

      I too worked at a company where with nolock was the defacto default on a query, cause yeah, no locking, so faster, so better.

      Its the most dangerouse query hint I can think of, closely followed by join hints.
      To many use hints without understanding the implications because they read some out of context snippet on the internet. Could you include a little warning about the dangers of dirty reads in your post ? It lacks context, with your reply it makes a lot more sense, but not everyone reads all the coments.

      Delete
    2. Sven, I added a bit about NOLOCK issues at the very beginning of the post.

      Delete