지속적인 스캔에는 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.