2011-09-16 38 views
10

Không thêm with (Nolock) giảm tranh chấp khi chọn từ bảng tạm thời hoặc SQL Server đủ thông minh để không tạo tranh chấp trên bảng tạm thời ngay từ đầu?nolock trên bảng tạm thời trong SQL Server 2008

PS: Có, tôi nhận thức được sự nguy hiểm của READUNCOMMITTED.

select * from #myTempTable 

vs

select * from #myTempTable with (nolock) --is this faster? 

Trả lời

9

Bạn có thể sử dụng dấu vết cờ 1200 (trên một máy phát triển như tôi nghĩ rằng đây là toàn cầu) để xem ổ khóa đưa ra cho chính mình

SET NOCOUNT ON; 

CREATE TABLE ##T 
(
X INT 
) 

INSERT INTO ##T 
SELECT number 
FROM master..spt_values 

CREATE TABLE #T 
(
X INT 
) 
INSERT INTO #T 
SELECT * 
FROM ##T 

/*Run the commands first with the trace flag off so the locking 
info is less full of irrelevant stuff about plan compilation 
*/ 
GO 

PRINT '##T Read Committed' 
SELECT COUNT(*) FROM ##T 
PRINT '##T NOLOCK' 
SELECT COUNT(*) FROM ##T WITH (NOLOCK) 
PRINT '##T Finished' 

GO 

PRINT '#T Read Committed' 
SELECT COUNT(*) FROM #T 
PRINT '#T NOLOCK' 
SELECT COUNT(*) FROM #T WITH (NOLOCK) 
PRINT '#T Finished' 

GO 

DBCC TRACEON(-1,3604) 
DBCC TRACEON(-1,1200) 

GO 

PRINT '##T Read Committed' 
SELECT COUNT(*) FROM ##T 
PRINT '##T NOLOCK' 
SELECT COUNT(*) FROM ##T WITH (NOLOCK) 
PRINT '##T Finished' 

GO 

PRINT '#T Read Committed' 
SELECT COUNT(*) FROM #T 
PRINT '#T NOLOCK' 
SELECT COUNT(*) FROM #T WITH (NOLOCK) 
PRINT '#T Finished' 

GO 

DBCC TRACEOFF(-1,3604) 
DBCC TRACEOFF(-1,1200) 

DROP TABLE ##T 
DROP TABLE #T 

Đối với một bảng tạm thời toàn cầu nó gì ngạc nhiên làm cho nhiều hơn một sự khác biệt.

Mặc dù vậy, vẫn có một khác biệt nhỏ về loại khóa cho các bảng địa phương #temp. Tôi sinh sản mà một phần của đầu ra dưới đây

#T Read Committed 
Process 56 acquiring IS lock on OBJECT: 2:301244128:0 (class bit0 ref1) result: OK 

Process 56 acquiring S lock on OBJECT: 2:301244128:0 (class bit0 ref1) result: OK 

Process 56 releasing lock on OBJECT: 2:301244128:0 

#T NOLOCK 
Process 56 acquiring Sch-S lock on OBJECT: 2:301244128:0 (class bit0 ref1) result: OK 

Process 56 acquiring S lock on HOBT: 2:9079256880114171904 [BULK_OPERATION] (class bit0 ref1) result: OK 

Process 56 releasing lock on OBJECT: 2:301244128:0 

Edit: Kết quả trên là dành cho một đống. Đối với các bảng tạm thời với chỉ số nhóm, kết quả sẽ được hiển thị bên dưới.

#T Read Committed 
Process 55 acquiring IS lock on OBJECT: 2:1790629422:0 (class bit0 ref1) result: OK 

Process 55 acquiring S lock on OBJECT: 2:1790629422:0 (class bit0 ref1) result: OK 

Process 55 releasing lock on OBJECT: 2:1790629422:0 

#T NOLOCK 
Process 55 acquiring Sch-S lock on OBJECT: 2:1790629422:0 (class bit0 ref1) result: OK 

Process 55 releasing lock on OBJECT: 2:1790629422:0 

#T Finished 

Lý do khóa BULK_OPERATION trên phiên bản heap là explained here. Nhưng nó có thể được nhìn thấy rằng các chi phí khóa là khá tối thiểu bất cứ điều gì.

+0

Câu trả lời rất hay. Tôi không biết về cờ theo dõi hữu ích này! Lưu ý rằng tập lệnh của bạn không cần vô hiệu hóa 3604 trên toàn cầu vào cuối thử nghiệm. Tôi đã kích hoạt cờ khởi động này trên hộp dev của tôi. Tôi nghĩ bạn nên sử dụng nó trong phạm vi phiên. Tuy nhiên, vì lý do nào đó, điều này đã không hoạt động với 1200. Tại sao 1200 phải là toàn cầu? – usr

+0

Tôi tin rằng trong số các thông số bạn đã chuyển đến 'DBCC TRACEON' & 'DBCC TRACEOFF', bạn nên chuyển cờ theo dõi làm tham số đầu tiên và chỉ báo toàn cục làm chỉ số cuối cùng. Tại sao bạn đặt '-1' làm cái đầu tiên? –

+0

@OgrishMan nó hoạt động giống nhau theo bất kỳ thứ tự nào. –

5

Đó là khó có khả năng thực hiện nhiều sự khác biệt kể từ phạm vi các bảng tạm thời là cùng một kết nối.

Bạn chỉ đang cạnh tranh cho khóa với chính mình trong cùng một kết nối và nếu bạn đang đọc bảng tạm thời, thì có thể bạn là người duy nhất làm như vậy.

Nói chung, có lẽ tốt hơn là không quá tối ưu hóa và tin tưởng công cụ truy vấn SQL Server để thực hiện tốt công việc của mình. Chờ cho đến khi bạn có một vấn đề trước khi bạn cố gắng sửa chữa bất cứ điều gì.

EDIT (hơi lạc đề): (cập nhật link)

Tuy nhiên, có một số cuộc thảo luận xung quanh ảnh hưởng đến toàn bộ tempdb khi bạn tạo một bảng tạm thời. Có thể tối ưu hóa - see options here (tuy nhiên đó là một bài viết cũ - SQL Server 6.5/7.0) và khả năng SQL Server 2000 trở lên của nó có giao dịch với kịch bản đó tự động

Một lần nữa, tôi khuyên bạn nên đợi cho đến khi có vấn đề làm phức tạp giải pháp của bạn.

+0

ps - tôi đã có vấn đề về tối ưu hóa :) – dan

0

Nó có thể tạo sự khác biệt lớn tùy thuộc vào truy vấn của bạn. Tôi đã giảm thời gian thực hiện truy vấn từ 1295 xuống 590 chỉ bằng cách thêm WITH (NO LOCK) trên bảng tạm thời của tôi. Kết quả có thể thay đổi.

Các vấn đề liên quan