Tại sao truy vấn của tôi đột nhiên chậm hơn so với ngày hôm qua?


76

[Lời chào]

(kiểm tra một)

[ ] Well trained professional, [ ] Casual reader, [ ] Hapless wanderer,

Tôi có một (kiểm tra tất cả những gì áp dụng)

[ ] query [ ] stored procedure [ ] database thing maybe  

đã chạy tốt (nếu có)

[ ] yesterday [ ] in recent memory [ ] at some point 

nhưng bây giờ đột nhiên chậm hơn

Tôi đã kiểm tra để đảm bảo rằng nó không bị chặn và đó không phải là nạn nhân của một số nhiệm vụ bảo trì, báo cáo hoặc hoạt động ngoài quy trình khác.

Vấn đề là gì, tôi nên làm gì và tôi có thể cung cấp thông tin gì để nhận được sự giúp đỡ?

[*Insert appropriate closing remarks*]

Câu trả lời:


88

Kính gửi [tên của bạn ở đây]!

Ồ không, tôi rất tiếc khi nghe điều đó! Hãy bắt đầu với một số điều cơ bản để giúp bạn cố định trong nháy mắt.

Thứ bạn đang chạy vào được gọi là Thông số đánh hơi

Đó là một cách giải quyết vấn đề kỳ lạ. Cái tên lăn ngay khỏi lưỡi. Giống như từ tiếng Đức cho con sóc.

Và đó thường là bạn của bạn.

Khi một truy vấn đến máy chủ của bạn, một kế hoạch phải được biên dịch. Để tiết kiệm thời gian và tài nguyên sau này, một kế hoạch thực hiện được lưu trữ dựa trên các hàng ước tính mà tham số đó sẽ khiến mã của bạn xử lý và trả về.

Cách dễ nhất để hình dung điều này trở nên tồi tệ là tưởng tượng một thủ tục được lưu trữ cần phải đếm mọi thứ từ hai quần thể bị lệch.

Ví dụ:

  • Những người mặc áo sơ mi CrossFit không bị thương: Không

  • Những người mặc áo sơ mi CrossFit nhăn nhó khi họ nhăn nhó: Tất cả

Rõ ràng, một lần thực thi mã đó sẽ phải thực hiện nhiều công việc hơn so với mã khác và các kế hoạch truy vấn bạn muốn thực hiện với số lượng công việc hoàn toàn khác nhau sẽ trông hoàn toàn khác nhau.

Tôi đang chống lại cái gì?

Đây là một vấn đề thực sự khó khăn để tìm, kiểm tra và sửa chữa.

  • Thật khó để tìm thấy bởi vì nó không xảy ra một cách nhất quán
  • Thật khó để kiểm tra vì bạn cần biết tham số nào gây ra các gói khác nhau
  • Thật khó để sửa vì đôi khi nó yêu cầu điều chỉnh truy vấn và chỉ mục
  • Thật khó để sửa vì bạn không thể thay đổi truy vấn hoặc chỉ mục
  • Thật khó để sửa vì ngay cả khi bạn thay đổi truy vấn hoặc chỉ mục, nó vẫn có thể quay lại

Sửa chữa nhanh chóng

Đôi khi, tất cả những gì bạn cần là một chút rõ ràng. Hay đúng hơn, bộ nhớ cache kế hoạch của bạn không.

Nếu đó là một thủ tục được lưu trữ

Hãy thử chạy EXEC sys.sp_recompile @objname = N'schema.procname'. Điều đó sẽ khiến thủ tục biên dịch lại một kế hoạch mới vào lần tiếp theo.

Điều này sẽ không khắc phục:

  • Các quy trình hiện đang chạy nó.

Điều này không đảm bảo:

  • Quá trình tiếp theo chạy sau khi biên dịch lại sẽ sử dụng một tham số cung cấp cho bạn một kế hoạch tốt.

Bạn cũng có thể chỉ sp_recompilevào một bảng hoặc dạng xem, nhưng được báo trước rằng tất cả các mã chạm vào bảng hoặc dạng xem đó sẽ biên dịch lại. Điều này có thể làm cho vấn đề khó khăn hơn rất nhiều.

Nếu đó là một truy vấn tham số

Công việc của bạn khó khăn hơn một chút. Bạn sẽ cần theo dõi SQL Xử lý. Bạn không muốn giải phóng toàn bộ bộ nhớ cache của gói - giống như sử dụng sp_recompilebảng hoặc chế độ xem, bạn có thể kích hoạt (ha ha ha) toàn bộ hậu quả không lường trước được.

Cách dễ nhất để tìm ra lệnh đó là chạy sp_BlitzWho *! Có một cột được gọi là "sửa lỗi đánh hơi tham số" có lệnh xóa một kế hoạch duy nhất khỏi bộ đệm. Điều này có nhược điểm tương tự như biên dịch lại, mặc dù.

Điều này sẽ không khắc phục:

  • Các quy trình hiện đang chạy nó.

Điều này không đảm bảo:

  • Quá trình tiếp theo chạy sau khi biên dịch lại sẽ sử dụng một tham số cung cấp cho bạn một kế hoạch tốt.

Tôi vẫn cần giúp đỡ!

Chúng ta sẽ cần những thứ sau đây:

  • Kế hoạch truy vấn tốt, nếu có thể
  • Kế hoạch truy vấn xấu
  • Các tham số được sử dụng
  • Các truy vấn trong câu hỏi
  • Định nghĩa bảng và chỉ mục

Lấy kế hoạch truy vấn và truy vấn

Nếu truy vấn đang chạy, bạn có thể sử dụng sp_BlitzWho * hoặc sp_WhoIsActive để chụp các truy vấn hiện đang thực thi.

EXEC sp_BlitzWho;

EXEC sp_WhoIsActive @get_plans = 1;

QUẢ HẠCH

Nếu truy vấn hiện không thực thi, bạn có thể kiểm tra nó trong bộ đệm của gói, sử dụng sp_BlitzCache *.

Nếu bạn đang sử dụng SQL Server 2016+ và đã bật Cửa hàng truy vấn, bạn có thể sử dụng sp_BlitzQueryStore *.

EXEC dbo.sp_BlitzCache @StoredProcName = 'Your Mom';

EXEC dbo.sp_BlitzQueryStore @StoredProcName = 'Your Mom';

Những thứ này sẽ giúp bạn theo dõi (các) phiên bản được lưu trong bộ nhớ cache của Quy trình được lưu trữ của bạn. Nếu đó chỉ là mã tham số, việc tìm kiếm của bạn khó khăn hơn một chút. Điều này có thể giúp, mặc dù:

EXEC dbo.sp_BlitzCache @QueryFilter = 'statement';

Bạn sẽ thấy đầu ra khá giống nhau từ bất kỳ trong số đó. Một lần nữa, kế hoạch truy vấn mời cột nhấp chuột màu xanh mát mẻ là bạn của bạn.

QUẢ HẠCH

Cách dễ nhất để chia sẻ các gói là sử dụng Dán Kế hoạch * hoặc bỏ XML vào pastebin. Để có được điều đó, nhấp vào một trong những cột nhấp chuột màu xanh mời. Gói truy vấn của bạn sẽ xuất hiện trong tab SSMS mới.

QUẢ HẠCH

Nếu bạn cảm thấy chia sẻ mã và truy vấn của công ty, bạn có thể sử dụng công cụ Plan Explorer miễn phí của Sentry One để ẩn danh kế hoạch của bạn. Hãy ghi nhớ, điều này làm cho việc trợ giúp trở nên khó khăn hơn - mã ẩn danh khó đọc hơn rất nhiều.

Tất cả các công cụ chúng tôi đã nói về sẽ trả về Văn bản truy vấn. Bạn không cần phải làm gì khác ở đây.

Lấy (các) tham số khó hơn một chút. Nếu bạn đang sử dụng Plan Explorer , có một tab ở phía dưới liệt kê tất cả chúng cho bạn.

QUẢ HẠCH

Nếu bạn đang sử dụng sp_BlitzCache *, có một cột có thể nhấp để cung cấp cho bạn câu lệnh thực thi cho các thủ tục được lưu trữ.

QUẢ HẠCH

Lấy định nghĩa bảng và chỉ mục

Bạn có thể dễ dàng nhấp chuột phải vào SSMS để viết kịch bản.

QUẢ HẠCH

Nếu bạn muốn có được mọi thứ trong một lần bắn, sp_Blitz Index * có thể giúp đỡ nếu bạn chỉ trực tiếp vào bàn.

EXEC dbo.sp_BlitzIndex @DatabaseName = 'StackOverflow2010',
                       @SchemaName = 'dbo',
                       @TableName = 'Users';

Điều này sẽ cung cấp cho bạn định nghĩa bảng (mặc dù không phải là câu lệnh tạo) và tạo câu lệnh cho tất cả các chỉ mục của bạn.

Thu thập và thêm thông tin này vào câu hỏi của bạn sẽ giúp mọi người có đủ thông tin để trợ giúp hoặc chỉ cho bạn đi đúng hướng.

Tôi muốn tự làm điều đó!

Chà, tuyệt. Tôi mừng cho bạn. Bạn điên người.

Có rất nhiều cách mọi người nghĩ rằng họ "sửa" tham số đánh hơi:

Nhưng những điều này thực sự chỉ vô hiệu hóa thông số đánh hơi theo những cách khác nhau. Điều đó không có nghĩa là họ không thể giải quyết vấn đề, họ chỉ không thực sự đi đến nguyên nhân gốc rễ.

Đó là bởi vì đi đến nguyên nhân gốc rễ thường là loại khó khăn. Bạn phải tìm kiếm những "vấn đề chất lượng kế hoạch" phiền phức.

Bắt đầu với các kế hoạch nhanh và chậm, tìm kiếm sự khác biệt như:

  • Chỉ mục được sử dụng
  • Tham gia đặt hàng
  • Nối tiếp song song

Đồng thời tìm kiếm các toán tử khác nhau làm cho mã của bạn nhạy cảm với việc đánh hơi tham số:

  • Tra cứu
  • Sắp xếp
  • Tham gia loại
  • Cấp bộ nhớ (và bằng cách mở rộng, tràn)
  • Ống cuốn

Đừng quá bận tâm trong việc tìm kiếm so với quét, phân mảnh chỉ mục hoặc bất kỳ nội dung nào trong giáo phái hàng hóa mà mọi người tìm kiếm.

Thông thường, có một vấn đề lập chỉ mục khá cơ bản. Đôi khi mã cần viết lại một chút.

Nếu bạn muốn tìm hiểu thêm về đánh hơi thông số:

Nếu bạn đang đọc bài này và bạn nghĩ rằng tôi đã bỏ lỡ một liên kết hoặc công cụ hữu ích, hãy để lại nhận xét. Tôi sẽ làm hết sức mình để cập nhật điều này.



28

Việc đánh hơi tham số không phải là nguyên nhân duy nhất có thể cho hiệu suất thay đổi của truy vấn. Bất kỳ lý do phổ biến sau đây có thể cho thấy các triệu chứng tương tự:

  1. Phân phối / khối lượng dữ liệu đã thay đổi, vượt qua điểm tới hạn của cây tìm kiếm tối ưu hóa
  2. Các chỉ mục / tệp bị phân mảnh
  3. Số liệu thống kê đã được cập nhật / thêm / giảm hoặc trở nên cũ và sai lệch do thay đổi dữ liệu
  4. Việc sử dụng bộ nhớ Windows đã thay đổi
  5. Nhật ký giao dịch đầy đủ và không cắt ngắn, gây ra việc mở rộng tệp vật lý lặp đi lặp lại
  6. Lược đồ đã thay đổi - chỉ mục / chế độ xem được lập chỉ mục / cột / ràng buộc được thêm, sửa đổi hoặc loại bỏ, loại dữ liệu đã thay đổi, v.v.
  7. Thay đổi cài đặt cờ theo dõi
  8. Cập nhật Windows đã được áp dụng
  9. Thay đổi cài đặt cơ sở dữ liệu hoặc máy chủ
  10. Cấp độ máy chủ CU đã thay đổi
  11. Cài đặt phiên ứng dụng khách đã thay đổi

Các mục 6 - 11 trong danh sách này chỉ có thể xảy ra sau khi một số hành động rõ ràng được thực hiện. Tôi đoán bạn muốn loại trừ những điều đó, nhưng nhiều lần người gặp phải thử thách, không biết rằng ai đó đã thực hiện thay đổi và điều đó đáng để kiểm tra trước khi bạn bắt đầu con đường xóa các mục trong bộ nhớ cache của kế hoạch.


1
Cảm ơn đã chỉnh sửa Paul. @sp_BlitzErik - Tôi không có ý định cung cấp lời khuyên về các chủ đề cụ thể, chỉ để nâng cao nhận thức rằng chúng tồn tại và có thể đáng để kiểm tra. Điều này không có nghĩa là làm giảm từ bài viết tuyệt vời của bạn. Bạn xử lý thông số đánh hơi theo chiều sâu, chuyên nghiệp và hài hước. Tôi rất thích đọc nó. Tôi chỉ muốn chắc chắn rằng nếu ai đó ở đây truy cập bài đăng này, theo tiêu đề hấp dẫn, anh ấy / cô ấy được biết về các nguyên nhân tiềm năng thay thế. IMHO nó thêm giá trị cho bài viết của bạn, nhưng nếu bạn vẫn muốn tôi xóa nó, hãy cho tôi biết.
SQLRaptor

Không hoàn toàn không. Tôi sẽ không bao giờ yêu cầu ai đó xóa một câu trả lời không chính xác hoặc có hại. Tôi vẫn nghĩ rằng bạn có thể thêm một số chi tiết, nhưng điều đó cuối cùng tùy thuộc vào bạn.
Erik Darling

10

Chỉ cần thêm vào các câu trả lời hiện có trong trường hợp họ không giúp đỡ, khi "đột nhiên" các truy vấn của bạn hoạt động khác vào ngày hôm sau, hãy kiểm tra:

  • Có phải lược đồ cho các bảng đã sử dụng thay đổi kể từ lần trước không? Trong trường hợp SSMS, bạn có thể nhấp chuột phải vào máy chủ trong Object Explorer và chọn Reports → Standard Reports → Schema Changes History.
  • Số lượng mặt hàng tăng đáng kể? Có thể truy vấn của bạn chậm hơn rất nhiều khi có nhiều dữ liệu trong các bảng được sử dụng.
  • Có ai khác sử dụng cơ sở dữ liệu cùng lúc với bạn không? Có thể chọn các khe thời gian mà bạn không can thiệp vào công việc của nhau.
  • Thống kê hệ thống đang tìm kiếm như thế nào? Có thể máy chủ đang nóng và đang điều chỉnh CPU hoặc ổ cứng sắp hết dung lượng hoặc trao đổi. Có thể có một vấn đề phần cứng khác như hỏa hoạn hoặc lũ lụt trong phòng máy chủ.

7

Một khả năng khác là Nhóm Cơ sở hạ tầng của bạn đang sử dụng các công cụ như vMotion trên VMware và VM hỗ trợ phiên bản SQL của bạn đang được chuyển liên tục từ Máy chủ sang Máy chủ mà không có DBA biết về nó.

Đây là một vấn đề thực sự khi Cơ sở hạ tầng của bạn không có nguồn gốc ... Tôi đang gặp ác mộng thực sự với nó.

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.