SET ARITHABORT ON이 쿼리 속도를 크게 높이는 이유는 무엇입니까?


74

쿼리는 많은 그룹화 수준과 통합 작업을 포함하는 단일 선택입니다. SET ARITHABORT ON을 사용하면 1 초도 걸리지 않으며, 그렇지 않으면 몇 분이 걸립니다. 우리는 SQL Server 2000 및 2008에서이 동작을 보았습니다.

답변:


62

조금 날짜가 있지만 비슷한 문제로 여기에 끝나는 사람은 ...

나는 같은 문제가 있었다. 나를 위해 그것은 매개 변수 스니핑으로 밝혀졌습니다. 처음에는 관심이 충분하지 않았습니다. 문제를 해결 한 'set arithabort on'을 추가했지만 다시 돌아 왔습니다. 그런 다음 읽었습니다.

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

모든 것을 정리했습니다. Linq to SQL을 사용하고 문제를 해결하기위한 제한된 옵션이 있었기 때문에 원하는 쿼리 계획을 강요하기 위해 쿼리 계획 가이드 (링크 끝 참조)를 사용했습니다.


3
6 년이 지난 후에도이 답변에 제공된 링크는 여전히 "읽기 필수"입니다. 그리고 여전히 최신 버전이며, '17 년 12 월의 최신 개정판입니다.
takrl

30

.NET 응용 프로그램은 기본적으로 비활성화 된 옵션으로 연결되지만 Management Studio에서는 기본적으로 활성화됩니다. 결과적으로 서버는 실제로 대부분 / 모든 프로 시저에 대해 2 개의 개별 실행 계획을 캐시합니다. 이것은 서버가 수치 계산을 수행하는 방법에 영향을 미치므로 절차에 따라 크게 다른 결과를 얻을 수 있습니다. 이것은 실제로 proc가 끔찍한 실행 계획을 얻을 수있는 두 가지 일반적인 방법 중 하나 일 뿐이며, 다른 하나는 매개 변수 스니핑입니다.

https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance를 살펴보십시오 . 그것에 대한 약간의 토론을 위해 aspx .


이 답변의 절반에 동의합니다. 그래도 수치 계산 주장에 대해 회의적입니다!
Martin Smith

2
@Martin : 확실하지 않은 것 같습니다. ARITHABORT ON을 사용하면 SQL Server가 div / 0 또는 산술 오버플로 오류에서 오류가 발생합니다. 꺼져 있으면 계속 진행되며 어떤 이유로 든 모든 종류의 끔찍한 문제가 발생할 수 있습니다.

@Ben-네 죄송합니다. 특히 귀하의 답변을 공격하고 싶지는 않습니다. SET옵션 을 변경하는 것이 매우 쉽다는 것을 지적하고 더 나은 계획을 세우고 잘못 된 옵션 자체로 잘못 진단했습니다. 나는 당신의 링크에있는 사람이 이것을하지 않았다고 확신하지 않습니다.
마틴 스미스

@Martin-문제 없습니다, 당신이 나를 공격하고 있다고 생각하지 않았습니다. 내가 연결 한 다른 토론은 약간 불분명 할 수 있습니다. 나는 단지 증거를 제공하려고 노력했다.

@Martin 회고하면 당신이 맞다고 생각합니다.

21

나는 이것이 거의 확실하게 매개 변수 스니핑이라고 주장합니다.

종종 SET OPTIONS이런 식으로 성능에 영향을 줄 수 있다고 언급되어 있지만 인덱스 된 뷰 / 지속적 계산 열을 사용하는 경우를 제외하고는이 클레임에 대한 단일 권한 소스를 아직 보지 못했습니다.

이 경우 (SQL2005 +의 경우 및 데이터베이스가 SQL2000 호환 모드가 아닌 경우 ). 당신이 모두있는 경우 ARITHABORT그리고 ANSI_WARNINGS OFF당신이 너무 시크 원하는보다는 스캔 할 수 있습니다 사용되지 않는 인덱스 발견 할 것이다 (그리고 지속 된 계산 결과로 약간의 오버 헤드를 사용할 수 없습니다). ADO.NET은 ANSI_WARNINGS ON내가 방금 한 빠른 테스트 를 기본으로하는 것 같습니다 .

"서버가 수치 계산을 수행하는 방법"이 결과에 몇 분을 더할 수 있다는 Ben의 답변에 대한 주장 은 그렇지 않으면 1 초도 걸리지 않습니다. 필자는 성능 성능 문제를 조사 할 때 프로파일 러가 문제가되는 쿼리를 식별하는 데 사용된다고 생각합니다. 이를 관리 스튜디오에 붙여 넣고 즉시 결과를 반환합니다. 연결 사이의 명백한 차이점은 ARITH_ABORT옵션입니다.

관리 스튜디오 창에서 빠른 테스트를 수행하면 SET ARITHABORT OFF켜져 있을 때 성능 문제가 다시 발생하여 쿼리가 실행되어 쿼리가 실행 된 것으로 나타납니다. 실제로 이것은 Gregg Stark 링크에 사용 된 문제 해결 방법 인 것 같습니다 .

그러나이 옵션을 설정하면 캐시에서 똑같은 잘못된 계획 얻을 수 있다는 사실을 무시합니다 .

이 계획 재사용은 애플리케이션 연결이 사용하는 것과 다른 사용자로 로그인 한 경우에도 발생할 수 있습니다.

웹 응용 프로그램에서 먼저 테스트 쿼리를 실행 한 다음 관리 스튜디오에서 테스트 쿼리를 실행하여 아래 테스트 SET ARITHABORT OFF에서 사용 횟수를 확인할 수 있습니다.

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) 

이 공유 pf 계획이 실제로 발생하려면 모든 계획 캐시 키가 동일해야합니다. 뿐만 아니라 arithabort실행중인 사용자에게 동일한 기본 스키마가 필요하고 (쿼리가 암시 적 이름 확인에 의존하는 경우) 연결에 동일한 language세트 가 필요한 경우도 있습니다.

계획 캐시 키의 전체 목록


12

나는이 파티에 늦었다는 것을 알고 있지만, 미래의 방문객들에게는 Martin이 정확히 맞습니다. 동일한 문제가 발생했습니다. SP는 .NET 클라이언트에서 매우 느리게 실행되는 반면 SSMS에서는 빠른 속도로 실행되었습니다. 이 문제를 탐색하고 해결하면서 Kenny Evitt가 Martin의 질문에 대한 논평에서 묻는 체계적인 테스트를 수행했습니다.

Martin의 쿼리 변형을 사용하여 프로 시저 캐시에서 SP를 찾아서 두 개를 찾았습니다. 계획을 살펴보면 실제로 하나는 ARITHABORT ON이고 다른 하나는 ARITHABORT OFF였습니다. ARITHABORT OFF 버전에는 인덱스 탐색이 있었지만 ARITHABORT ON 버전은 동일한 출력에 대해 인덱스 스캔을 사용했습니다. 관련된 매개 변수를 고려할 때, 인덱스 탐색은 출력을 위해 수천만 개의 레코드를 검색해야했습니다.

캐시에서 두 가지 절차를 지우고 .NET 클라이언트가 동일한 매개 변수를 사용하여 SP를 다시 실행하게했습니다 (여러 활동이 많은 고객에게는 광범위한 날짜 범위가 있음). SP가 즉시 돌아 왔습니다. 캐시 된 계획은 이전에 ARITHABORT ON 계획에서 기능했던 것과 동일한 인덱스 스캔을 사용했지만 이번에는 ARITHABORT OFF 계획이었습니다. SSMS에서 동일한 매개 변수를 사용하여 SP를 실행하고 다시 결과를 즉시 얻었습니다. 이제 ARITHABORT ON에 대한 두 번째 계획이 인덱스 스캔과 함께 캐시되는 것을 보았습니다.

그런 다음 캐시를 지우고 좁은 날짜 범위로 SSMS에서 SP를 실행 한 후 즉시 결과를 얻었습니다. 결과 캐시 된 계획에 인덱스 탐색이 있었으며 동일한 출력이 이전에 스캔으로 처리되었으므로 (ARITHABORT가 OFF 인 원래 계획에서도 탐색 했음). SSMS에서도 이번에는 동일한 넓은 날짜 범위로 SP를 실행했으며 원래 .NET 요청에서와 동일한 끔찍한 성능을 보았습니다.

요컨대, 불균형은 ARITHABORT의 실제 가치와 관계가 없었습니다. 어느 클라이언트에서든 켜거나 끄면 수용 할 수 있거나 끔찍한 성능을 얻을 수 있습니다. 중요한 것은 계획을 컴파일하고 캐싱하는 데 사용되는 매개 변수 값이었습니다.

하지만 MSDN이 ARITHABORT OFF 자체는 쿼리 최적화에 부정적인 영향을 미칠 수 있음을 나타냅니다, 우리의 테스트는 마틴이 올바른지 확인 - 원인이 매개 변수 스니핑하고, 생성 된 계획이 매개 변수의 모든 범위에 대한 최적되지 않는.


1
그 문구의 Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.의미가 궁금 합니다. 계산 된 열과 뷰에서 인덱스를 사용할 수 없다는 ( ANSI_WARNINGS또는 꺼져있는 경우) 또는 실제로 다른 영향을 미치는지 여부에 대해 이야기 합니다.
Martin Smith

잘 모르겠습니다. MSDN의 누군가가 비슷한 상황을 겪고 ARTIHABORT를 ON으로 설정하고 성능이 향상되었으며 다른 사람들과 동일한 결론을 내린 경우가 아닌지 궁금합니다. 인덱싱 된 뷰와 계산 열까지는 확실하지 않습니다. 어느 시점에서, INSERT, UPDATE 또는 DELETE 조작이 저장된 데이터 값을 수정하는 경우 SET 옵션은 특정 값을 가져야합니다. 다른 곳에서는 옵티마이 저가 인덱스 된 뷰 또는 계산 열을 참조하는 "모든 쿼리"에 대한 인덱스를 무시할 것이라고 명시하고 있습니다. 둘 다 맞습니까? 아니면 실제로 "데이터를 수정하는 쿼리"입니까?
mdoyle

1

이 문제가 발생했습니다. 사람들이 여기에서 말한 것처럼, 근본 원인은 여러 쿼리 계획으로, 그 중 하나는 차선책입니다. ARITHABORT가 실제로 문제를 일으킬 수 있는지 확인하고 싶었습니다 (질문에서 매개 변수 스니핑을 수행하는 매개 변수가없는 쿼리에 문제가 있었기 때문에).


1

이것은 SQL Server 2008 일에서 겪었던 것과 동일한 문제를 상기시킵니다. 우리의 경우 갑자기 하나의 SQL 작업이 갑자기 느려지고 (보통 몇 초, 이제 9 분 이상) 작업이 연결된 서버에 액세스해야하며 작업 단계에서 ARITHABORT 설정을 추가하여 문제가있는 것으로 나타났습니다. 며칠 동안 해결되어 돌아 왔습니다.

우리는 나중에 MS 지원으로 티켓을 열었고 처음에는 둘 중 하나를 찾을 수 없었으며 티켓은 매우 고위 PFE 팀으로 이관되었으며 두 명의 지원 PFE 가이 문제를 파악하려고했습니다.

마지막 이유는 작업 단계를 실행하기위한 사용자 신임 정보가 연결된 서버 측의 기본 테이블 통계에 액세스 할 수 없으므로 실행 계획이 최적화되지 않았기 때문입니다.

구체적으로, 사용자는 DBCC SHOW_STATISTICS 에 대한 권한이 없습니다 (사용자는 테이블에서 SELECT 할 수 있음). MSDN 에 따르면 이 권한 규칙은 sql 2012 SP1 이후에 변경됩니다.

SQL Server 및 SQL 데이터베이스에 대한 권한

통계 오브젝트를 보려면 사용자는 테이블을 소유해야하거나 사용자는 sysadmin 고정 서버 역할, db_owner 고정 데이터베이스 역할 또는 db_ddladmin 고정 데이터베이스 역할의 구성원이어야합니다.

SQL Server 2012 SP1은 권한 제한을 수정하고 SELECT 권한이있는 사용자가이 명령을 사용할 수 있도록합니다. SELECT 권한이 명령을 실행하기에 충분하려면 다음 요구 사항이 있습니다.

이 문제를 확인하려면 연결된 서버 측 인스턴스에서 프로파일 러를 실행하고 아래 표시된대로 "오류 및 경고"섹션에서 일부 이벤트를 설정하면됩니다.

여기에 이미지 설명을 입력하십시오

이 경험이 어떻게 든 커뮤니티에 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.