Tại sao SET ARITHABORT ON tăng tốc đáng kể một truy vấn?


75

Truy vấn là một lựa chọn duy nhất chứa nhiều cấp độ nhóm và hoạt động tích cực. Với SET ARITHABORT ON chỉ mất chưa đến một giây, nếu không thì mất vài phút. Chúng tôi đã thấy hành vi này trên SQL Server 2000 và 2008.

Câu trả lời:


62

Một chút hẹn hò, nhưng đối với bất kỳ ai kết thúc ở đây với một vấn đề tương tự ...

Tôi đã từng gặp vấn đề tương tự. Đối với tôi, nó hóa ra là thông số đánh hơi, mà lúc đầu tôi không đủ hiểu để quan tâm. Tôi đã thêm một 'thiết lập arithabort' để khắc phục sự cố nhưng sau đó nó đã quay trở lại. Sau đó tôi đọc:

http://www.sommarskog.se/query-plan-mysteries.html

Nó xóa mọi thứ - lên. Vì tôi đang sử dụng Linq to SQL và có các tùy chọn hạn chế để khắc phục sự cố, tôi đã kết thúc bằng cách sử dụng hướng dẫn kế hoạch truy vấn (xem phần cuối của liên kết) để buộc kế hoạch truy vấn tôi muốn.


3
Hơn sáu năm sau, liên kết được đưa ra trong câu trả lời này vẫn là "yêu cầu đọc" ... và vẫn còn hiện hành, phiên bản mới nhất là ngày 17 tháng 12.
takrl

30

Các ứng dụng .NET kết nối với tùy chọn bị tắt theo mặc định, nhưng nó được bật theo mặc định trong Management Studio. Kết quả là máy chủ thực sự lưu trữ 2 kế hoạch thực hiện riêng cho hầu hết / tất cả các thủ tục. Điều này ảnh hưởng đến cách máy chủ thực hiện các phép tính số và do đó bạn có thể nhận được các kết quả khác nhau tùy thuộc vào quy trình. Đây thực sự chỉ là một trong 2 cách phổ biến mà một Proc có thể được cung cấp cho một kế hoạch thực hiện khủng khiếp, còn lại là thông số đánh hơi.

Hãy xem https://web.archive.org/web/20150315031719/http://sqladvice.com/bloss/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance. aspx cho một chút thảo luận về nó.


Tôi đồng ý với một nửa câu trả lời này. Tôi rất hoài nghi về yêu cầu tính toán số mặc dù!
Martin Smith

2
@Martin: Tôi nghĩ rằng tôi đã không rõ ràng. Tôi chỉ nói rằng ARITHABORT ON làm cho SQL Server sẽ báo lỗi về bất kỳ lỗi tràn div / 0 hoặc số học nào. Khi nó tắt nó tiếp tục và vì bất kỳ lý do gì có thể gây ra tất cả các loại vấn đề khủng khiếp.

@Ben - Vâng xin lỗi tôi không muốn đặc biệt tấn công câu trả lời của bạn tôi chỉ chỉ ra rằng nó sẽ rất dễ dàng để thay đổi một SETtùy chọn được một kế hoạch tốt hơn và misdiagnose này như là lựa chọn riêng của mình đó là có lỗi. Tôi không tin anh chàng trong liên kết của bạn đã không làm điều này.
Martin Smith

@Martin - Không thành vấn đề, tôi không nghĩ bạn đang tấn công tôi. Các cuộc thảo luận khác mà tôi liên kết có thể không rõ ràng. Tôi chỉ cố gắng đưa ra bằng chứng hỗ trợ.

@Martin Nhìn lại tôi tin rằng bạn đúng.

21

Tôi sẽ tranh luận rằng điều này gần như chắc chắn là thông số đánh hơi.

Nó thường được tuyên bố rằng SET OPTIONScó thể ảnh hưởng đến hiệu suất theo cách này nhưng tôi vẫn chưa thấy một nguồn có thẩm quyền duy nhất cho khiếu nại này ngoại trừ trường hợp bạn đang sử dụng các cột được xem được lập chỉ mục / các cột được tính toán.

Trong trường hợp này (đối với SQL2005 + và trừ khi cơ sở dữ liệu của bạn ở chế độ tương thích SQL2000 ). Nếu bạn có cả hai ARITHABORTANSI_WARNINGS OFFsau đó bạn sẽ thấy chỉ mục không được sử dụng, do đó có thể quét chứ không phải tìm kiếm mong muốn (và một số chi phí như kết quả tính toán không thể sử dụng). ADO.NET dường như mặc định có ANSI_WARNINGS ONtừ một bài kiểm tra nhanh tôi vừa làm.

Khiếu nại trong câu trả lời của Ben rằng "cách máy chủ thực hiện các phép tính số" có thể thêm vài phút vào kết quả mà nếu không mất ít hơn một giây thì dường như không đáng tin đối với tôi. Tôi nghĩ những gì có xu hướng xảy ra là khi điều tra một vấn đề về hiệu năng hoạt động, Profiler được sử dụng để xác định truy vấn vi phạm. Điều này được dán vào phòng quản lý và chạy và trả về kết quả ngay lập tức. Sự khác biệt rõ ràng duy nhất giữa các kết nối là ARITH_ABORTtùy chọn.

Một thử nghiệm nhanh trong cửa sổ phòng quản lý cho thấy rằng khi SET ARITHABORT OFFđược bật và truy vấn được chạy thì vấn đề hiệu suất sẽ tái diễn do đó rõ ràng là trường hợp đã đóng. Quả thực đây có vẻ là phương pháp khắc phục sự cố được sử dụng trong liên kết Gregg Stark .

Tuy nhiên, bỏ qua thực tế là với tùy chọn đó, bạn có thể nhận được cùng một kế hoạch xấu chính xác từ bộ đệm .

Việc sử dụng lại gói này có thể xảy ra ngay cả khi bạn đăng nhập với tư cách người dùng khác với kết nối ứng dụng sử dụng.

Tôi đã kiểm tra điều này bằng cách thực hiện một truy vấn kiểm tra trước tiên từ một ứng dụng web sau đó từ phòng quản lý SET ARITHABORT OFFvà có thể thấy các thông số tăng lên từ truy vấn bên dưới.

SELECT usecounts, cacheobjtype, objtype, text ,query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 

Để việc chia sẻ này, các kế hoạch pf thực sự xảy ra, tất cả các khóa bộ đệm của kế hoạch phải giống nhau. Cũng như arithabortmột số ví dụ khác là người dùng thực thi cần cùng một lược đồ mặc định (nếu truy vấn dựa vào độ phân giải tên ẩn) và các kết nối cần cùng một languagebộ.

Một danh sách đầy đủ hơn các khóa bộ nhớ cache kế hoạch ở đây


13

Tôi biết tôi đến bữa tiệc muộn này, nhưng đối với những vị khách tương lai, Martin hoàn toàn chính xác. Chúng tôi gặp vấn đề tương tự - một SP chạy rất chậm đối với các máy khách .NET, trong khi nó rất nhanh cho SSMS. Khi khám phá và giải quyết vấn đề, chúng tôi đã thực hiện bài kiểm tra có hệ thống mà Kenny Evitt hỏi về bình luận của anh ấy cho câu hỏi của Martin.

Sử dụng một biến thể của truy vấn của Martin, tôi tìm SP trong bộ đệm thủ tục và tìm thấy hai trong số chúng. Nhìn vào các kế hoạch, trên thực tế, đó là trường hợp một người có ARITHABORT ON và một người đã tắt ARITHABORT. Phiên bản ARITHABORT OFF có tìm kiếm chỉ mục trong khi phiên bản ARITHABORT ON sử dụng quét chỉ mục cho cùng một đầu ra. Với các tham số liên quan, tìm kiếm chỉ mục sẽ yêu cầu tra cứu hàng chục triệu bản ghi cho đầu ra.

Tôi đã xóa hai thủ tục khỏi bộ đệm và để máy khách .NET chạy lại SP, sử dụng cùng một tham số (có phạm vi ngày rộng cho một khách hàng có nhiều hoạt động). SP trở lại ngay lập tức. Kế hoạch được lưu trong bộ nhớ cache đã sử dụng chức năng quét chỉ mục tương tự đã được nêu trong kế hoạch ARITHABORT ON - nhưng lần này kế hoạch dành cho ARITHABORT OFF. Chúng tôi đã chạy SP với các tham số tương tự trong SSMS và một lần nữa nhận được kết quả ngay lập tức. Bây giờ chúng tôi đã thấy rằng một kế hoạch thứ hai đã được lưu trữ, cho ARITHABORT ON, với quét chỉ mục.

Sau đó chúng tôi đã xóa bộ nhớ cache, chạy SP trong SSMS với phạm vi ngày hẹp và nhận được kết quả ngay lập tức. Chúng tôi thấy rằng kế hoạch lưu trữ kết quả có tìm kiếm chỉ mục, cho cùng một đầu ra đã được xử lý trước đó bằng quét (cũng là một tìm kiếm trong kế hoạch ban đầu với ARITHABORT OFF). Một lần nữa từ SSMS, chúng tôi đã chạy SP, lần này với cùng một phạm vi ngày rộng và thấy hiệu suất khủng khiếp tương tự như chúng tôi có trong yêu cầu .NET ban đầu.

Nói tóm lại, sự chênh lệch không liên quan gì đến giá trị thực tế của ARITHABORT - với hoặc tắt, từ một trong hai máy khách, chúng ta có thể có hiệu suất chấp nhận được hoặc khủng khiếp: Tất cả những gì quan trọng là các giá trị tham số được sử dụng trong việc biên dịch và lưu trữ kế hoạch.

Mặc dù MSDN chỉ ra rằng chính ARITHABORT OFF có thể có tác động tiêu cực đến tối ưu hóa truy vấn, thử nghiệm của chúng tôi xác nhận rằng Martin là chính xác - nguyên nhân là do đánh hơi tham số và kế hoạch kết quả không tối ưu cho tất cả các phạm vi tham số.


1
Tự hỏi cụm từ đó Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.có nghĩa là gì. Cho dù họ chỉ nói về việc không thể sử dụng các chỉ mục trên các cột và chế độ xem được tính toán (nếu ANSI_WARNINGScũng bị tắt) hoặc nếu nó thực sự có một số hiệu ứng khác.
Martin Smith

Tôi không chắc. Tôi tự hỏi liệu có đơn giản là trường hợp ai đó ở MSDN gặp phải tình huống tương tự, đặt ARTIHABORT thành BẬT, thấy sự cải thiện hiệu suất và nhảy đến kết luận tương tự mà người khác có. Theo như các khung nhìn được lập chỉ mục và các cột được tính toán, tôi không rõ ràng. Tại một thời điểm, nó nói rằng các tùy chọn SET phải có các giá trị cụ thể nếu một thao tác INSERT, UPDATE hoặc DELETE sửa đổi các giá trị dữ liệu được lưu trữ trong đó. Ở những nơi khác, họ tuyên bố rằng trình tối ưu hóa sẽ bỏ qua các chỉ mục cho "mọi truy vấn" tham chiếu đến chế độ xem được lập chỉ mục hoặc cột được tính toán. Cả hai đều đúng, hay nó thực sự là "bất kỳ dữ liệu sửa đổi truy vấn" nào?
mdoyle

1

Chỉ có vấn đề này. Như mọi người đã nói ở đây, nguyên nhân gốc rễ là nhiều kế hoạch truy vấn, một trong số đó là tối ưu phụ. Tôi chỉ muốn xác minh rằng ARITHABORT thực sự có thể tự gây ra sự cố (vì truy vấn tôi gặp vấn đề không có tham số, tham số này đánh hơi ra khỏi phương trình).


1

Điều này nhắc nhở tôi chính xác vấn đề tương tự tôi gặp phải trong máy chủ sql 2008 ngày. Trong trường hợp của chúng tôi, chúng tôi đột nhiên thấy một công việc sql đột nhiên chậm lại (thường là vài giây và bây giờ là hơn 9 phút), công việc cần truy cập vào một máy chủ được liên kết, chúng tôi đã thêm cài đặt ARITHABORT trong bước của công việc và có vẻ như vấn đề đã được giải quyết trong một vài ngày và sau đó trở lại.

Sau đó, chúng tôi đã mở một vé với sự hỗ trợ của MS và ban đầu họ cũng không thể tìm ra, và vé đã được chuyển đến một nhóm PFE rất cao cấp và hai PFE hỗ trợ đã cố gắng tìm ra vấn đề này.

Lý do cuối cùng là thông tin đăng nhập của người dùng (để chạy bước công việc) không thể truy cập số liệu thống kê của các bảng bên dưới (ở phía máy chủ được liên kết) và do đó kế hoạch thực hiện không được tối ưu hóa.

Cụ thể, người dùng không có quyền trên DBCC SHOW_STATISTICS (mặc dù người dùng có thể CHỌN từ bảng). Theo MSDN , quy tắc cấp phép này được thay đổi sau sql 2012 SP1

Quyền cho SQL Server và cơ sở dữ liệu SQL

Để xem đối tượng thống kê, người dùng phải sở hữu bảng hoặc người dùng phải là thành viên của vai trò máy chủ cố định sysadmin, vai trò cơ sở dữ liệu cố định db_owner hoặc vai trò cơ sở dữ liệu cố định db_ddladmin.

SQL Server 2012 SP1 sửa đổi các hạn chế quyền và cho phép người dùng có quyền CHỌN sử dụng lệnh này. Lưu ý rằng các yêu cầu sau tồn tại để quyền CHỌN đủ để chạy lệnh:

Để xác minh vấn đề này, chúng ta chỉ cần chạy trình lược tả trên phiên bản phía máy chủ được liên kết và bật một số sự kiện trong phần "Lỗi và Cảnh báo" như hiển thị bên dưới.

nhập mô tả hình ảnh ở đây

Hy vọng kinh nghiệm này có thể giúp cộng đồng bằng cách nào đó.

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.