지속적인 스캔에는 0 초 또는 2-3 분이 소요됩니다


9

아래의 쿼리와 같이 행을 반환하지 않는 쿼리는 서버 중 하나에서 0 ~ 160 초가 걸립니다.

select col1, col2, col3
from tab1
where 0 = 1

2 주 전에는 48 시간 간격으로 6 번 발생했습니다. 지난주에 같은 쿼리가 ~ 0 초 걸렸습니다. 응용 프로그램의 SQL 로그가 있지만 아직 용의자를 찾지 못했습니다. 게다가, 최상위 0 / where 0 = 1 유형 쿼리가 데이터 페이지에 절대로 도달하지 않는다고 생각했기 때문에 행 / 페이지 / 테이블 수준 데이터 잠금에 저항해야합니까? 스키마는 알려진 SQL에 의해 영향을받지 않습니다.

문제가 일관 적이 지 않고 서버의 부하가 너무 높기 때문에 SQL 프로파일 러를 연결하기 전에 발생하는 문제의 이론을 이해하고 싶습니다. 이러한 지연 동안 다른 쿼리는 문제없이 실행됩니다. 응용 프로그램의 알려진 문제는 동적으로 생성 된 많은 수의 SQL 쿼리입니다. 48 시간 동안 총 850k (로그 된) 쿼리의 약 200k 고유 쿼리가 이런 문제를 일으킬 수 있습니까?

서버는 SQL Server 2005 표준판, 96GB RAM, SAN 디스크 및 4 개의 CPU / 16 코어를 실행하고 있습니다. 데이터베이스 파일과 파일 그룹은 최적화되어 있으며 문제가되지 않습니다 (그러나 우리는 이것을 별도로 조사하고 있습니다).

어디를보아야하는지에 대한 조언은 대단히 감사합니다.

편집 : 완벽! 실행 계획을 추가하기 위해 쿼리를 재생했으며 1 분 35 초가 걸렸습니다. 쿼리 기간을 보여주는 실행 계획과 스크린 샷은 다음과 같습니다. 쿼리 계획

편집 2 : 두 번째 실행에 대한 통계 시간 세부 사항. 지금은 꾸준히 느려질 것이므로 프로파일 러와 perfmon을 연결할 것입니다.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 97402 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

실행 계획을 포함시켜 주시겠습니까? 실행하기 전에 쿼리 창의 CTRL + M
Craig Efrein

2
잠금 문제 일 수 있습니까? 테이블에서 선택을 차단하는 다른 세션의 DML 문 (SQL Server 2005의 기본 동작)
a_horse_with_no_name

내가 생각할 수있는 유일한 원인 인 알려진 DML 문은 없지만 아직 조사 중입니다. 실행 계획이 질문에 추가됩니다.
EventHorizon

내가 읽은 것으로부터, 이것은 옵티마이
저가

1
이처럼 보이는 케이스를 보았습니다. 업데이트 통계를 트리거하는 것으로 나타났습니다 (자동 업데이트 통계가 켜져 있고 유지 관리 계획이 중단되었습니다).
Joshua

답변:


18

테이블에서 인 ... WHERE 0 = 1텐트 공유 ( IS) 잠금에 대한 요구 사항이 여전히 존재 하는 조항이 있는 것처럼 보입니다 . 이것을 증명합시다 :

테스트 테이블을 생성하여 시작하겠습니다.

use TestDb1;
go

create table dbo.MyTestTable1
(
    Id int identity(1, 1) not null,
    SomeInt int not null
);
go

insert into dbo.MyTestTable1 (SomeInt)
values (10), (20), (30), (40), (50);
go

이제 테스트 테이블이 있으므로 한 세션 (쿼리 창)에서 독점 ( X) 잠금 을 설정하기 위해 다음을 실행합니다 dbo.MyTestTable1.

use TestDb1;
go

begin tran;
    select
        Id, SomeInt
    from dbo.MyTestTable1 with (tablockx);
--commit tran;

sys.dm_tran_locksDMV 를 보면 독점 잠금을 확인할 수 있습니다 . 그런 다음 다른 세션 (새 쿼리 창)에서 쿼리가 수행하는 작업을 정확하게 수행합니다.

use TestDb1;
go

select
    Id, SomeInt
from dbo.MyTestTable1
where 0 = 1;

언뜻보기에 완료되지 않은 것을 알 수 있습니다. 를 보면 sys.dm_exec_requests, 이것이 왜 그런지 정확히 알 수 있습니다.

select
    r.session_id,
    r.status,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    r.blocking_session_id
from sys.dm_exec_requests r
cross apply sys.dm_exec_sql_text(r.sql_handle) st
where st.text like '%where 0 = 1%'
and r.session_id <> @@spid;

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

... WHERE 0 = 1쿼리 IS가이 객체 에 대한 잠금을 기다리고 있음을 알 수 있습니다 (object_id가로 변환 됨 dbo.MyTestTable1).

나는 동시성이 당신의 문제 라고 말하지는 않지만 그 소리에 의해 당신은 증상을 보이고 있습니다. 위의 예 WHERE는 절대 데이터를 반환하지 않는 절로 도 잠금 및 차단이 면제되지 않음을 증명하는 것 입니다.

우리가 할 수있는 일은 추측뿐입니다. "오래 걸렸을 때"해야 할 일은 그 요청이 무엇을하고 있는지 정확히 보는 것입니다. 무언가를 기다리고 있다면 무엇을 기다리고 있는지보십시오.


1

쿼리를 까다로운 스레드가 얼마나 까다로운 지에 따라 시스템에서 해당 쿼리를 큐에 대기시키고있을 수 있습니다. 설정에 대한 기본 작업자 수 (즉, 동시 SQL 서버 스레드 수)는 약 700이어야합니다.

sys.dm_os_schedulers 및 sys.dm_os_waiting_tasks를 확인하여 문제가 있는지 확인하십시오.


좋은 제안이지만 결국 문제는 어리석은 자물쇠였습니다.
EventHorizon

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