Bảng temp chậm giảm trong sql 2005


7

Tôi đã gặp phải một vấn đề trên máy chủ sql sản xuất của chúng tôi, nơi các đối tượng bảng tạm thời mất nhiều thời gian để thả (rõ ràng khi sử dụng thả nhỏ và đồng bộ). Tôi không thể sao chép điều này trên các máy chủ sql khác (tương tự như vậy với cùng số lượng trục chính phục vụ các tệp dữ liệu tempdb (chia thành cùng một số tệp (1 cho mỗi lõi vật lý)). Trên SQL 2005 Enterprise (SP2 - 3042).

Cập nhật: một yếu tố nữa - đó là khả năng cao nhất. máy chủ này có> 500 cơ sở dữ liệu trên đó. Một máy chủ khác có> 800 cũng chạy những giọt này chậm. Đó là máy chủ khác duy nhất tôi có với rất nhiều dbs trên đó.

Cập nhật thứ hai: khởi động lại các máy chủ có vấn đề sẽ cho phép các câu lệnh tạo và thả thực thi ngay lập tức. Hiệu suất của bài kiểm tra xuống cấp trong vài giờ tới (trong khi ứng dụng đang chạy) cho đến khi nó đạt (điều dường như là) một cao nguyên. Tôi đã có một công việc đang chạy trong nền đang thử nghiệm điều này cứ sau 30 phút. Tôi sẽ xem kết quả sau vài ngày và xem thời gian thực hiện có giống nhau không. Tôi nghĩ rằng họ sẽ được.

Cập nhật lần thứ ba: Mặc dù không có câu lệnh thực thi nào cho thấy chốt chờ trên tài nguyên CPU, nhưng sử dụng sp_whoisactive tôi thấy rằng trong khi chạy delta_interval = 30 (giây), khi chạy truy vấn CPU_delta báo cáo khoảng 30.000 (mili giây?) Và khi tôi xem hoàn hảo trong khi thực thi dường như có một giá trị cốt lõi của cpu tăng đột biến trong thời gian thực hiện. đây là trên 16 hộp cpu nên có thể hơi khó nhìn qua perfmon khi có lưu lượng khác xảy ra, nhưng dường như nó đang tăng giá trị cpu trong khi thực hiện các câu lệnh thả.

Tạo và hủy 20 bảng tạm thời nhỏ với các tên duy nhất (một cột, không có hàng) chỉ mất chưa đến 20ms trên hầu hết các máy chủ mà tôi kiểm tra. Trên một máy chủ phải mất> 5 giây. Phần lớn thời gian (> 95%) được dành cho các báo cáo thả.

Trong quá trình thực thi, không có sự chờ đợi rõ ràng và không có báo cáo chặn nào và perfmon không hiển thị bất kỳ tải nào trên hệ thống con I / O cho dữ liệu hoặc tệp nhật ký.

Tôi đã xem xét thời gian sử dụng cao nhất và thấp, khi số lượng bảng cao được đánh dấu cho sự phá hủy và thấp. Hoạt động mất 5 giây hoặc lâu hơn để xử lý 20 câu lệnh thả, không có vấn đề gì. Vấn đề đang gây ra sự chậm lại có thể nhận thấy (bởi khách hàng) đối với khả năng đáp ứng.

Mã mẫu, tôi đã tạo 20 đối tượng giống như để có thời gian 5 giây. Nó xuất hiện là khoảng 300ms mỗi giọt.

PRINT CONVERT(varchar(30),GETDATE(),113)


CREATE TABLE [#Objects1]
(
  [Id] uniqueidentifier NOT NULL
)


CREATE TABLE [#Objects12]
(
  [Id] uniqueidentifier NOT NULL
)
...
DROP TABLE [#Objects1]
DROP TABLE [#Objects12]
...
PRINT CONVERT(varchar(30),GETDATE(),113)

Thời gian liên tục 5 đến 6 giây để thực hiện

11 tháng 11 năm 2011 12: 56: 52: 073 - Bắt đầu tạo bảng tạm thời

11 tháng 11 năm 2011 12: 56: 52: 090 - Kết thúc việc tạo bảng tạm thời

11 tháng 11 năm 2011 12: 56: 52: 090 - Bắt đầu thả bảng tạm thời

11 tháng 11 năm 2011 12: 56: 57: 230 - Hoàn thành thả bảng tạm thời

Bạn cũng có thể chạy USE tempdb; ĐĂNG KÝ DBCC; và ghi lại số lượng hàng trả về. Vui lòng thêm tất cả đầu ra từ các tập lệnh vào câu hỏi ban đầu của bạn.

Ban đầu tôi nhận thấy rằng tôi có khoảng 271 vlog, vì vậy tôi đã thu nhỏ lại và xem liệu phân mảnh có phải là vấn đề không. Không có sự khác biệt. Thông tin đăng nhập DBCC hiện tại

FileId,FileSize,StartOffset,FSeqNo,Status,Parity,CreateLSN
2,253952,8192,101603,2,64,0
2,262144,262144,101604,2,64,0
2,262144,524288,101605,2,64,85000000038300574
2,262144,786432,101606,2,64,85000000038300574
2,262144,1048576,101578,2,128,86000000001600001
2,262144,1310720,101579,2,128,86000000001600001
2,262144,1572864,101580,2,128,86000000001600001
2,262144,1835008,101581,2,128,86000000001600001
2,262144,2097152,101582,2,128,86000000001600001
2,262144,2359296,101583,2,128,86000000023400002
2,262144,2621440,101584,2,128,86000000023500756
2,327680,2883584,101585,2,128,86000000023500756
2,327680,3211264,101586,2,128,86000000023500756
2,393216,3538944,101587,2,128,86000000023500756
2,393216,3932160,101588,2,128,86000000023500756
2,458752,4325376,101589,2,128,86000000023500756
2,253952,4784128,101590,2,128,86000000023500756
2,270336,5038080,101591,2,128,86000000023500756
2,253952,5308416,101592,2,128,86000000023500756
2,270336,5562368,101593,2,128,86000000023500756
2,253952,5832704,101594,2,128,86000000023500756
2,335872,6086656,101595,2,128,86000000023500756
2,253952,6422528,101596,2,128,86000000023500756
2,401408,6676480,101597,2,128,86000000023500756
2,253952,7077888,101598,2,128,86000000023500756
2,466944,7331840,101599,2,128,86000000023500756
2,253952,7798784,101600,2,128,86000000023500756
2,253952,8052736,101601,2,128,86000000023500756
2,278528,8306688,101602,2,128,86000000023500756
2,133627904,8585216,101607,2,64,101336000000013600462
2,133627904,142213120,101563,0,128,101336000000013600462
2,133627904,275841024,101564,0,128,101336000000013600462
2,133627904,409468928,101565,0,128,101336000000013600462
2,133627904,543096832,101566,0,128,101336000000013600462
2,133627904,676724736,101567,0,128,101336000000013600462
2,133627904,810352640,101568,0,128,101336000000013600462
2,133627904,943980544,101569,0,128,101336000000013600462
2,133627904,1077608448,101570,0,128,101336000000013600462
2,133627904,1211236352,101571,0,128,101336000000013600462
2,133627904,1344864256,101572,0,128,101336000000013600462
2,133627904,1478492160,101573,0,128,101336000000013600462
2,133627904,1612120064,101574,0,128,101336000000013600462
2,133627904,1745747968,101575,2,128,101336000000013600462
2,133627904,1879375872,101576,2,128,101336000000013600462
2,134479872,2013003776,101577,2,128,101336000000013600462

Đầu ra thống kê IO :

Database Name,physical_name,io_stall_read_ms,num_of_reads,avg_read_stall_ms,io_stall_write_ms,num_of_writes,avg_write_stall_ms,io_stalls,total_io,avg_io_stall_ms
msdb,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MSDBData.mdf,47691565,817329,58.4,10747142,533509,20.1,58438707,1350838,43.3
tempdb,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\templog.ldf,54457,30177,1.8,145691717,8235651,17.7,145746174,8265828,17.6
model,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\modellog.ldf,547,122,4.4,2273,239,9.5,2820,361,7.8
tempdb,P:\tempdb_data3.mdf,2606066,1112043,2.3,17829023,1919954,9.3,20435089,3031997,6.7
tempdb,P:\tempdb_data2.mdf,2484793,1111808,2.2,17270161,1922735,9.0,19754954,3034543,6.5
tempdb,P:\tempdb_data5.mdf,2514469,1112086,2.3,17066589,1919802,8.9,19581058,3031888,6.5
tempdb,P:\tempdb_data7.mdf,2542070,1112551,2.3,17049649,1920204,8.9,19591719,3032755,6.5
tempdb,P:\tempdb_data6.mdf,2517767,1112237,2.3,17043756,1924983,8.9,19561523,3037220,6.4
tempdb,P:\tempdb_data0.mdf,2476811,1113570,2.2,17084779,1926333,8.9,19561590,3039903,6.4
tempdb,P:\tempdb_data4.mdf,2462179,1111649,2.2,17073336,1920058,8.9,19535515,3031707,6.4
tempdb,P:\tempdb_data1.mdf,2456317,1111859,2.2,16997589,1922438,8.8,19453906,3034297,6.4
model,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\model.mdf,5194,798,6.5,612,240,2.5,5806,1038,5.6
master,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf,40640,7326,5.5,2868,1548,1.9,43508,8874,4.9
msdb,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MSDBLog.ldf,8015,950,8.4,1012107,312084,3.2,1020122,313034,3.3
master,H:\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\mastlog.ldf,640,141,4.5,198283,99134,2.0,198923,99275,2.0

Đầu ra Waitstats :

wait_type,wait_time_s,pct,running_pct

PAGEIOLATCH_EX,0.02,100.00,100.00

TokenAndPermUserStore kích thước là 2952kb.

SELECT SUM(single_pages_kb + multi_pages_kb) AS "SecurityTokenCacheSize(kb)" FROM sys.dm_os_memory_clerks WHERE name = 'TokenAndPermUserStore' 

tempdb là 8 tệp dữ liệu trên một cuộc đột kích 10 SAN lun. Không nơi nào áp lực không gian trên các tệp dữ liệu (thường ở đâu đó khoảng 500 MB 48 GB ...) hộp SQL có 4 procs lõi tứ. Nhật ký tập tin là trên các trục chính riêng biệt. Thật không may, các bảng tạm thời không thể được xử lý xung quanh mà không cần tìm kiếm lớn và là một thành phần của chiến lược chèn số lượng lớn để lấy dữ liệu vào các bảng tạm thời để sẵn sàng cho các procs được lưu trữ hoạt động.

1
Cùng @@ PHIÊN BẢN trên tất cả các Máy chủ SQL? Sau đó kiểm tra các công tắc khởi động để tìm cờ theo dõi trên tất cả các máy chủ
gbn

3
Bây giờ hãy kiểm tra cờ theo dõi ... không phải là mã
gbn

4
Nếu bạn TRUCATEcác bảng tạm thời đầu tiên, nó sẽ tăng tốc DROP. Ha, đùa thôi.
Nick Chammas

1
Chỉ khi bảng> 8MB. Đối với các bảng temp được lưu trữ, có một bộ đệm của dữ liệu meta. Đây là nơi những nghi ngờ của tôi nằm ... Nhưng tôi không chắc phải tìm những bảng được lưu trong bộ nhớ cache này ở đâu. Nếu nó chỉ là sys.objects trong tempdb thì chỉ có 2k đối tượng. Tôi không thể tưởng tượng tại sao điều đó lại quá chậm để thêm / thả.
JorgeSandoval

Câu trả lời:


8

Bạn đã không đề cập đến IOPS được sử dụng bởi tempdb LUN. Bạn có thấy bất kỳ IO chờ đợi nào trên thiết bị LUN không? Có bất cứ điều gì khác trên LUN đó? Là một hệ thống khác sử dụng nhóm / nhóm đĩa mà LUN được khắc từ?

Ditto master db - cùng q.

Ngoài ra, bạn có đang sử dụng bảng tạm thời cục bộ (#tablename) hoặc bảng tạm thời toàn cầu (## tablename) không? Nếu SPID toàn cầu khác có thể giữ khóa chia sẻ trên các bảng tạm thời toàn cầu khi bạn đang cố xóa chúng không?


Các tệp dữ liệu Tempdb nằm trên LUN nằm trong nhóm 10 đĩa đột kích của riêng nó (tức là các trục chính chuyên dụng). Không có tải i / o nào được hiển thị (tức là 98% hoặc cao hơn thời gian chờ trên đĩa logic). bảng tạm thời là bảng tạm thời cục bộ, (như trong ví dụ của tôi trong bài viết gốc). Có thể được sao chép khi nó không xuất hiện dưới tải.
JorgeSandoval

Ngoài ra tempdb ldf là vào cuộc đột kích 5
JorgeSandoval

Tôi nghĩ rằng @bretlowery là một cái gì đó. Bạn có thể THAY ĐỔI tempdb vào một LUN khác, khởi động lại, xem có gì thay đổi không. Ngoài ra, tôi sẽ không có LDF trên RAID 5: chúng ghi 100% và phù hợp hơn với R1 hoặc R10. Cuối cùng, kiểm tra cài đặt đĩa + bộ điều khiển (bộ nhớ đệm, trạng thái đột kích, v.v.)
gbn

Tôi sẽ không thấy một số tranh chấp cho đĩa ở đó, tỷ lệ sử dụng trong idletime% là gần 98/99%? Ý tôi là chúng ta đang nói về việc thả một bảng tạm thời với một cột. Đây phải là hai có thể ba thao tác ghi nhiều nhất, nhưng phải mất 300 ms sau khi máy chủ chạy trong một khoảng thời gian dài với ứng dụng đang chạy. Khởi động lại ví dụ và bạn nhận được các giọt siêu nhanh làm chậm trong vài giờ đầu tiên của ứng dụng chạy với nó.
JorgeSandoval

7

Câu trả lời cho vấn đề hoàn hảo của tôi là một vấn đề ít được biết đến (mặc dù tôi đã thấy nó từ lâu) liên quan đến việc thu thập số liệu thống kê dmv trên các hệ thống có nhiều cơ sở dữ liệu trong đó mã sử dụng bảng tạm thời rất nhiều (hoặc có lẽ bạn có rất nhiều bảng) . Trên các máy chủ chậm nhất của chúng tôi sys.dm_db_index_usage_stats có> 200k hồ sơ, với các máy chủ trả về các bản ghi 10k vẫn có độ trễ có thể đo được.

Bài viết KB mô tả vấn đề. http://support.microsoft.com/kb/2003031

Hiệu suất truy vấn giảm khi sys.dm_db_index_usage_stats có số lượng hàng lớn

Hãy xem xét kịch bản sau đây:

  • Trong Microsoft SQL Server 2005, bạn thường xuyên thực hiện thao tác DDL liên quan đến việc thả và giải trí rất nhiều bảng (đặc biệt là các bảng tạm thời trong cơ sở dữ liệu tempdb).
  • Bạn có một số lượng lớn các mục (100.000 trở lên) trong chế độ xem quản lý động sys.dm_db_index_usage_stats (DMV).

Vấn đề này được khắc phục trong SQL 2008, nhưng chỉ có thể được giảm bớt trong năm 2005 bằng cách thay đổi mã để giảm sự phụ thuộc vào các bảng tạm thời hoặc bằng cách bật cờ theo dõi 2330.

KB này đã lưu thịt xông khói của tôi. Khởi động lại sau khi thêm cờ theo dõi này để khởi động các thông số đã giảm thời gian thả xuống mức <100 ms (từ 40000 ms!) Và tôi cũng có thể mong đợi những lợi ích hoàn hảo khác trên các máy chủ này!

Đọc thêm dẫn tôi đến kết luận rằng đây là vấn đề

http://www.pythian.com/news/5211/sql-server-more-light-shed-on-non-yielding-scheduler-and-indexes-stats/

Cảm ơn tất cả những người đã đóng góp cho câu hỏi này, tôi đã có được khá nhiều công cụ rất hữu ích để chẩn đoán các vấn đề hoàn hảo trong quy trình.


1
Rất vui khi biết bạn đã tìm thấy một giải pháp và cảm ơn vì đã đăng chi tiết.
Mark Storey-Smith

1
Cảm ơn rất nhiều vì sự giúp đỡ của bạn, vấn đề dường như (đúng) như voodoo. Một luồng duy nhất chiếm một cpu hầu như không đáng chú ý trên một hộp lớn và không có bất kỳ sự chờ đợi nào, nó thực sự chỉ đang lướt qua bộ nhớ cache lớn cho các chỉ số này. Rất vui vì họ đã sửa lỗi này trong SQL 2008, bây giờ phải chờ khoảng thời gian dài từ bây giờ đến khi chúng tôi thực sự nâng cấp ...
JorgeSandoval

6

Khi một bảng thả đang chờ hơn một hoặc hai giây, hãy chạy sp_WhoIsActive của Adam Machanic . Đây là một công cụ tuyệt vời để tìm hiểu lý do tại sao bất kỳ truy vấn nào đang chạy chậm. Trong cột chờ, bạn sẽ thấy chờ đợi cho tác vụ cụ thể và nếu nó bị kẹt chờ CPU (sẽ không hiển thị trong sys.dm_os_wait_stats) bạn cũng sẽ thấy điều đó.

Ngoài ra, tôi sẽ cảm thấy hối hận nếu tôi không chỉ ra rằng bản dựng của bạn không hỗ trợ. Là một chuyên gia tư vấn, tôi nói với khách hàng của mình: "Tôi ghét phải xử lý sự cố hàng giờ chỉ để thấy rằng nó đã được sửa trong gói dịch vụ - và cuối cùng thanh toán cho bạn hàng ngàn đô la cho một thứ bạn có thể sửa miễn phí. Thêm vào đó bạn ' dù sao cũng không hỗ trợ. " Bạn có thể tìm thấy các gói dịch vụ SQL Server mới nhất và các bản cập nhật tích lũy tại http://sqlserverbuilds.blogspot.com . Build 3042 là cách hết hạn - phiên bản được hỗ trợ là SP4.


Vâng, tôi ước nó đơn giản như chỉ cập nhật lên gói dịch vụ sau này ... Tôi đã quét các bản cập nhật tích lũy và ghi chú sp và không thấy bất cứ điều gì liên quan đến vấn đề này. Thật không may, chính sách nợ ngăn chúng tôi cài đặt SQL SP mà không có kiểm tra hồi quy đầy đủ của ứng dụng có thể mất vài tháng. Các bài kiểm tra đơn vị trên ứng dụng này chiếm khoảng 20% ​​... thật đau đớn. Đây là một chuyến tàu chậm để di chuyển và chúng tôi đang chuẩn bị cho hoạt động đó để hỗ trợ anh ấy di chuyển đến Denali (hoặc nếu không được phát hành sớm SQL2008 R2)
JorgeSandoval

Tôi đã tải xuống sp_whoisactive Proc, nhưng để có được bất kỳ số liệu thống kê có ý nghĩa nào, tôi phải mở rộng việc thực hiện để tạo 50 bảng tạm thời và thả chúng xuống. Tổng số thực hiện của lô mất 43 giây. Tôi đã bắt đầu sp_whoisactive và chạy với delta = 30 giây để đảm bảo bắt đầu và dừng bao gồm đợt này. Dường như các câu lệnh đang đặt CPU dưới một áp lực nào đó (tốt, một lõi) trong thời gian thực hiện.
JorgeSandoval

Không rõ thời gian cpu của sp_whoisactive là mili giây hay micro giây. Có vẻ như một phần nghìn giây ở chỗ nó tương quan với khoảng thời gian delta, nhưng khi tôi tìm kiếm rất nhiều DMV họ báo cáo trong micro giây
JorgeSandoval

Yeha, Adam đã báo cáo nó trong một phần nghìn giây. Không sử dụng delta - bạn chỉ muốn chạy sp_WhoIsActive như tôi hiển thị trong video và bạn muốn bắt nó trong khi nó đang chờ thả bảng tạm thời. Điều đó có nghĩa là chạy nó trong một vòng lặp chặt chẽ, như mỗi giây và bắt đầu ra vào bảng tạm thời mỗi lần. Sau đó quay trở lại và kiểm tra các bảng tạm thời để xem những gì các spid đang chờ đợi mỗi lần, và nếu có bất kỳ chặn. Ngoài ra về các ghi chú - chúng sẽ không bao gồm mọi bản sửa lỗi có trong SP / CU và hãy nhớ rằng, bạn đang ở phiên bản không được hỗ trợ.
Brent Ozar

Cảm ơn về đầu vào, vấn đề là bộ sưu tập số liệu thống kê của chế độ xem (xem câu trả lời của tôi để biết thêm thông tin).
JorgeSandoval

5

Chỉnh sửa: 2011-11-12 13:00

Vì TokenAndPermStore có vẻ là kích thước "bình thường", nên không chắc là một yếu tố. Nơi tiếp theo để xem có lẽ là số liệu thống kê spinlock . Bạn cũng có thể (như tôi đã đề cập trong trò chuyện ) xác định xem vấn đề có còn tồn tại không nếu bạn loại bỏ các câu lệnh thả rõ ràng và để các bảng nằm ngoài phạm vi thay thế.

Chỉnh sửa: 2011-11-12 01:00

Là bạn trên 2005SP2, tôi bắt đầu tự hỏi liệu đây có phải là sự cố TokenAndPermUserStore không . Nó sẽ giải thích tại sao vấn đề được giảm bớt bằng cách khởi động lại cá thể và tại sao vấn đề lại phổ biến trên các máy chủ có số lượng lớn cơ sở dữ liệu.

Bạn có thể chạy truy vấn sau đây và thêm đầu ra cho câu hỏi của bạn.

SELECT SUM(single_pages_kb + multi_pages_kb) AS "SecurityTokenCacheSize(kb)"
FROM sys.dm_os_memory_clerks
WHERE name = 'TokenAndPermUserStore'

Cách khắc phục nhanh cho việc này là tạo một công việc theo dõi kích thước của bộ đệm và chạy DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')khi vượt quá một kích thước nhất định. IIRC (Tôi sẽ kiểm tra vào ngày mai và cập nhật) Tôi đã đặt giới hạn ở mức 100 MB trên các máy chủ nơi điều này gây ra sự cố. SP3 giới thiệu một cơ chế để kiểm soát kích thước bộ đệm , mà không cần phải vũ trang xóa nó.

Câu trả lời gốc:

Có thể mất một chút thời gian và nhưng chúng ta có thể bắt đầu bằng cách xem IOchờ thống kê không? (tập lệnh trong GIST)

Sửa đổi tập lệnh tạo / thả của bạn để chạy DBCC SQLPERF("sys.dm_os_wait_stats",CLEAR);khi bắt đầu, tiếp theo là tập lệnh thống kê chờ sau lần thả cuối cùng của bạn. Kết quả có thể sẽ dễ đọc hơn nếu bạn đăng chúng dưới dạng CSV (để chúng có thể được sao chép vào Excel).

Bạn cũng có thể chạy USE tempdb; DBCC LOGINFO;và ghi lại số lượng hàng trả về.


FYI sau khoảng 6 hoặc 7 lần thực hiện, có vẻ như chỉ chờ đợi trên PAGEIOLATCH_SHPAGEIOLATCH_SH 0.02 100.00 100.00
JorgeSandoval

Trung bình 6,5 hoặc hơn cho các tệp dữ liệu và 17,6 cho tệp nhật ký dường như không đóng góp cho 300ms cho mỗi bảng bị bỏ.
JorgeSandoval

Thật thú vị, tập lệnh thử nghiệm (tạo / xóa các bảng tạm thời) không trả về bất kỳ sự chờ đợi nào trên các máy chủ khác. (Chờ CTE thực sự báo cáo chia cho lỗi không).
JorgeSandoval

@JorgeSandoval bạn có thể thêm dữ liệu vào câu hỏi ban đầu của mình dưới dạng chỉnh sửa không. Bằng cách đó mọi người sẽ dễ dàng nhìn thấy hơn (và làm việc trên).
Mark Storey-Smith

kết quả đã được thêm vào
JorgeSandoval 11/11/11
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.