2013-08-13 1 views
1

EXECUTE 명령을 사용하는 두 번째 쿼리가 첫 번째 쿼리보다 4 배 빠른 속도로 실행되는 이유는 무엇입니까? 이 문제를 어떻게 해결할 수 있습니까?실행 쿼리 명령 (동적 SQL)이 일반 쿼리보다 빠르게 실행됩니다.

두 번째 경우에서 추가 테이블 (작업 가능)이 생성되는 이유는 무엇입니까?

변수 :

DECLARE @count INT, @followerId BIGINT 
SET @count=1024 
SET @followerId=10 

첫 번째 쿼리 (일반적인 쿼리) :

SELECT TOP (@count) Photo.* FROM Photo 
WHERE EXISTS (SELECT accountId FROM Follower 
WHERE [email protected] 
AND Follower.accountId = Photo.accountId) 
AND Photo.closed='False' 
ORDER BY Photo.createDate DESC 

로그 :

SQL 서버 구문 분석 및 컴파일 시간 : CPU 시간 = 0 ms, 경과 시간 = 7 ms.

SQL Server 실행 시간 : CPU 시간 = 0 ms, 경과 시간 = 0 ms.

'사진'. 스캔 카운트 952, 논리적 읽기 542435, 물리적 읽기 0, 미리 읽기 0, 로브 논리적 읽기 0, 로브 물리적 읽기 0, 로브 미리 읽기 0은 0을 읽습니다.

테이블 '따라 가기'. 스캔 횟수 1, 논리적 읽기 7, 물리적 읽기 0, 미리 읽기 0, 로브 논리적 읽기 0, 로브 물리적 읽기 0, 로브 미리 읽기 0은 0을 읽습니다.

SQL Server 실행 시간 : CPU 시간 = 1466 ms, 경과 시간 = 9620 ms.

실행 계획 :

First query execution plan

두 번째 쿼리 (EXECUTE와 같은 쿼리) :

EXEC ('SELECT TOP (' [email protected] + ') Photo.* FROM Photo 
WHERE EXISTS (SELECT accountId FROM Follower 
WHERE Follower.followerId=' [email protected] + ' 
AND Follower.accountId = Photo.accountId) 
AND Photo.closed=''False'' 
ORDER BY Photo.createDate DESC') 

로그 :

SQL Server 구문 분석 및 컴파일 시간 : CPU 시간 = 0 ms, 경과 시간 = 0 ms.

SQL Server 실행 시간 : CPU 시간 = 0 ms, 경과 시간 = 0 ms.

SQL Server 실행 시간 : CPU 시간 = 0 ms, 경과 시간 = 0 ms. SQL Server 구문 분석 및 컴파일 시간 : CPU 시간 = 25 ms, 경과 시간 = 25 ms.

테이블 '작업 테이블'. 스캔 카운트 0, 논리적 읽기 0, 물리적 읽기 0, 미리 읽기 0, 로브 논리적 읽기 0, 로브 물리적 읽기 0, 로브 미리 읽기 0으로 읽습니다.

테이블 '사진'. 스캔 카운트 952, 논리적 읽기 542707, 물리적 읽기 0, 미리 읽기 0, 로브 논리적 읽기 0, 로브 물리적 읽기 0, 로브 미리 읽기 0이 읽습니다.

테이블 '따라 가기'. 스캔 카운트 6, 논리적 읽기 9, 물리적 읽기 0, 미리 읽기 0, 로브 논리적 읽기 0, 로브 물리적 읽기 0, 로브 미리 읽기 0은 0을 읽습니다.

테이블 '작업 테이블'.스캔 횟수 0, 논리적 읽기 0, 물리적 읽기 0, 미리 읽기 0, 로브 논리적 읽기 0, 로브 물리적 읽기 0, 로브 미리 읽기 0은 0을 읽습니다.

SQL Server 실행 시간 : CPU 시간 = 1374 ms, 경과 시간 = 2140 ms.

SQL Server 실행 시간 : CPU 시간 = 1405 ms, 경과 시간 = 2165 ms.

답변

3

변수가 인라인 상수가되므로 두 번째 쿼리 (첫 번째 쿼리의 컨텍스트에 따라 다름)가 더 최적화 될 수 있습니다. 비교 :

DECLARE @count INT, @followerId BIGINT 
SET @count=1024 
SET @followerId=10 

SELECT TOP (@count) Photo.* FROM Photo 
WHERE EXISTS (SELECT accountId FROM Follower 
WHERE [email protected] 
AND Follower.accountId = Photo.accountId) 
AND Photo.closed='False' 
ORDER BY Photo.createDate DESC 

으로 :

SELECT TOP (1024) Photo.* FROM Photo 
WHERE EXISTS (SELECT accountId FROM Follower 
WHERE Follower.followerId=10 
AND Follower.accountId = Photo.accountId) 
AND Photo.closed='False' 
ORDER BY Photo.createDate DESC 

이 첫 번째 쿼리가 저장된 프로 시저의 일부라면, 변수를 인수했다 및 저장 될 때 특정 쿼리가 다른 매개 변수 값으로 최적화 된 더욱 그러하다 proc 컴파일되었습니다.

+0

다양한 조치를 취할 수 있습니다 (예 : 명령문에 OPTION RECOMPILE, OPTIMIZE FOR, 강제로 데이터베이스의 매개 변수화 설정 ... –

관련 문제