SQL 서버에서 높은 CPU 사용량-느린 쿼리 [닫기]


11

MS SQL Server는 CPU 전력의 약 95 %를 사용하고 있습니다.

서버 (하드웨어) 다시 시작 또는 SQL-Service 다시 시작 후 사용량은 0 %이며 1 ~ 3 일 동안 천천히 증가합니다. 사용량에 따라 다릅니다.

80 %를 초과하면 모든 쿼리가 매우 느립니다.

우리 웹 사이트는 많은 큰 쿼리를 처리하므로 일부는 45-60 초가 걸립니다. 재시작 후 (CPU 사용량이 80 % 미만) 동일한 쿼리에 대해 11-20 초가 걸립니다.


이 문제를 어떻게 해결할 수 있습니까? 선호도 마스크가 CPU 사용을 조정할 수 있지만 온라인 선호도 설정은 비활성화되어 있음을 온라인에서 읽었습니다. 변경할 수 없습니다. 프로세서가 하나 밖에 없기 때문에이 문제가 발생합니까?

검색어 자체와 관련된 많은 트릭이 있지만 웹 사이트와 서비스는 상당히 커서 변경하기에는 너무 많습니다.

그들 대부분은 이미 꽤 잘 최적화되어 있습니다.


사람들이 전화를 걸고 메시지를 녹음 할 수있는 알람 서비스가있어 선택한 그룹이 호출되어 녹음 된 메시지를들을 수 있기 때문에 2 초 밖에 걸리지 않지만 SQL-Service를 계속 다시 시작할 수 없습니다.

이 시스템은 수백 명의 수색 및 구조 팀에서 사용하며 경보 중에 SQL 서비스가 다시 시작되면 종료되고 호출 한 사람에게 통지되지 않습니다.


나는 모든 곳을 수색했지만 "Affinity Masks"에 관한 것을 제외하고는 아무것도 찾을 수 없었습니다.

현재 쿼리를 종료하지 않고 CPU 캐시를 지우는 방법이 있어야합니다.


SQL: Microsoft SQL Server 11.0.2100.60
OS: Windows Server 2012 x64
Processor: 2.30 GHz
RAM: 4.00 GB

의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Paul White 9

답변:


7

이것은 긴 샷이지만 강제 매개 변수 설정을 살펴볼 수 있습니다. 성능이 나빠질 때 많은 수의 쿼리 계획이 표시되는 경우 쿼리가 예상 한대로 캐시되지 않고 쿼리가 캐시를 통해 스캔하여 이미 사용할 계획이 있는지 확인하는 데 시간이 오래 걸립니다. 캐시를 지우면이 문제가 해결되면 강제 매개 변수 설정을 변경하는 것이 좋습니다. 다음을 사용하여 캐시를 지울 수 있습니다.

DBCC FREEPROCCACHE

캐시를 지우면 강제 매개 변수화 설정이 무엇인지 확인할 수 있습니다.

SELECT name
     , is_parameterization_forced
  FROM sys.databases;

아마도 기본값 인 0으로 설정되어있을 것입니다. 원하는 경우 다음을 수행하여이를 true로 설정할 수 있습니다.

ALTER DATABASE [database_name] SET PARAMETERIZATION FORCED;

이는 개발 환경에서 먼저 수행해야하며 이것이 다른 방식으로 데이터베이스에 부정적인 영향을 미치는지 확인하십시오. 다음을 사용하여 되돌릴 수 있습니다.

ALTER DATABASE [database_name] SET PARAMETERIZATION SIMPLE;

5
모든 쿼리는 이제 실행 계획을 다시 컴파일해야하기 때문에 프로 시저 캐시를 비우면 실제로 CPU가 급증 할 수 있습니다.
Aaron Bertrand

18

선호도는 "CPU 사용을 조정"하지 않습니다 (예를 들어 CPU가 더 적은 작업을 수행하도록 함). CPU를 끄거나 (같은 머신의 다른 인스턴스에서 사용 가능하도록) CPU를 I / O 만 지원하십시오. CPU가 여러 개인 경우에도 이전 CPU를 사용하여 목표를 달성 할 수 없으며, CPU 사용량이 많은 이유를 알지 못하므로 후자를 추측하는 것은 불가능합니다. 인덱싱이 극도로 열악하고 컴파일이 너무 많거나 스칼라 UDF가 풍부하고 I / O 스 래싱이 원인 일 수 있습니다. (그리고 I / O가 원인 일 수있는 이유는 데이터베이스가 3GB 이상인 경우 지속적으로 버퍼 풀 메모리 안팎으로 데이터를 교환해야하기 때문에 CPU에 많은 비용이 들기 때문입니다.)

CPU 캐시는 또한 내려갈 필요가없는 토끼 구멍입니다. CPU 캐시에 문제가있어 CPU가 95 %로 급격히 떨어질 것입니다.

CPU 압력 소스를 좁히고 저장 프로 시저를 사용한다고 가정하면 Glenn Berry ( 여기서 제공 ) 에서이 진단 쿼리를 살펴볼 수 있습니다 . 올바른 데이터베이스의 컨텍스트에서 실행하십시오.

-- Top Cached SPs By Total Worker time (SQL Server 2012). 
-- Worker time relates to CPU cost  (Query 44) (SP Worker Time)

SELECT TOP (25) 
  p.name AS [SP Name], 
  qs.total_worker_time AS [TotalWorkerTime], 
  qs.total_worker_time/qs.execution_count AS [AvgWorkerTime], 
  qs.execution_count, 
  ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) 
    AS [Calls/Second],
  qs.total_elapsed_time, 
  qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time], 
  qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

-- This helps you find the most expensive cached stored procedures from a CPU perspective
-- You should look at this if you see signs of CPU pressure

저장 프로 시저를 사용하지 않는 경우 John Samson의이 예제는 임시 쿼리 ( 여기에서 제공)를 격리하는 데 도움이 될 수 있습니다 .

SELECT TOP (25)
    qs.sql_handle,
    qs.execution_count,
    qs.total_worker_time AS Total_CPU,
    total_CPU_inSeconds = --Converted from microseconds
    qs.total_worker_time/1000000,
    average_CPU_inSeconds = --Converted from microseconds
    (qs.total_worker_time/1000000) / qs.execution_count,
    qs.total_elapsed_time,
    total_elapsed_time_inSeconds = --Converted from microseconds
    qs.total_elapsed_time/1000000,
    st.text,
    qp.query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

또한 현재 실행중인 모든 쿼리를 빠르게 분석하고 원하는 경우 (예 : 경우 ) 정렬 할 수있는 저장 프로 시저 인 Adam Machanic의 sp_WhoIsActive를 살펴볼 수도 있습니다 @sort_order = '[CPU] DESC'.

하지만 검색 및 구조 팀에 미션 크리티컬 한 경우 특히 하드웨어를 먼저 구매해야합니다. 응용 프로그램을 서비스하려면 더 많은 CPU와 더 많은 RAM이 있어야합니다. 또한 더 나은 고 가용성 (예 : 클러스터링, 미러링 또는 가용성 그룹)이 필요합니다. 물리적 시스템을 재부팅하여 애플리케이션을 완전히 오프라인 상태로 만들어야 할 이유는 없습니다.이 문제에 대한 더 나은 솔루션이 있습니다. 마지막으로이 "서버"에는 하나의 가시 디스크 드라이브 만 있다고 가정합니다. 이는 OS, SQL Server 데이터 파일, 로그 파일, tempdb 등의 모든 I / O가 단일 컨트롤러를 통해 단일 드라이브에서 읽기 / 쓰기 작업을 공유한다는 것을 의미합니다. 더 많은 디스크를 확보하십시오. 가능하면 SSD를 구하십시오. RAID를 사용하고 가능한 한 I / O를 분산 시키십시오.

그러나 문제에 하드웨어를 던지는 것이 해결책의 유일한 부분은 아닙니다. 과도한 CPU 사용을 유발하는 원인을 정확히 분리 한 다음 사용중인 하드웨어에 관계없이 해당 문제를 공격해야합니다.

다른 아이디어에 대해서는이 StackOverflow 질문을 참조하십시오.

/programming/945063/how-do-i-find-out-what-is-hammering-my-sql-server


0

다음 코드는 실제 코드를 볼 수 없기 때문에 '어두운 곳에서의 샷'입니다.

먼저 SP가 커서를 열고 열어 둔 상태 일 수 있습니다. 커서, 특히 닫기 및 할당 해제에서 커서를 읽습니다. 누군가 닫고 있지만 커서 할당을 해제하지 않았을 수 있습니다. 업그레이드로 인해 동작이 변경되었을 수 있습니다. 2012는 남은 커서를 2008 R2와 다르게 취급 할 수 있습니다.

두 번째는 정리되지 않은 테이블 잠금이있을 수 있다는 것입니다. 다시 말하지만, 나는 멀리 떨어져있어 말할 수는 없지만 누군가가 '거래 시작'후에 전역 임시 테이블을 만들고 '거래 종료'가 실행되지 않거나 저장 프로 시저가 잠긴 채로 두지 않는 것이 좋습니다 tempdb에서 공간을 차지하는 테이블.

우연히 WinLink를 사용하고 있습니까? 이것에 대해 뭔가 모호하게 들립니다.


-4

성능 향상을 위해 memcached와 같은 캐싱 메커니즘이 있어야합니다.


그러나 이것은 SQL-Server의 CPU 사용량을 바꾸지 않을 것입니다. 그것은 웹 사이트에서 쿼리가 더 빨리 진행되게하고 다른 사람이 같은 테이블에서 memcached 결과를 사용하는 동안 테이블에서 일부가 변경되는 문제가 발생할 수 있습니다.
Levi Johansen 2016 년

@Levi 쿼리 결과를 중간 계층 어딘가에 캐시하면 쿼리가 데이터베이스에 충돌하지 않습니다 (캐시를 새로 고쳐야 할 때 제외).
Aaron Bertrand

1
웹 사이트에 아무도 없을 때 CPU가 높으면 웹 레벨을 캐싱하는 것이 도움이되지 않습니다. Memcached는 훌륭한 도구이지만 유능한 사람이 앉아서 아무 것도하지 말아야 할 때 서버가 무엇을하고 있는지 알아 내기위한 대용품이 아닙니다.
TomTom 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.