2009-05-13 7 views
26

sp의 임시 테이블과이 모든 것이 동시성에 어떻게 영향을 미칠 수 있는지 궁금합니다. SP는 MSSQL 08 서버에서 제작되었습니다.저장 프로 시저의 임시 테이블

내가 임시 테이블을 만들고 다음과 같이 다시 드롭 SP에있는 경우 :

BEGIN 

CREATE TABLE #MyTempTable 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

... Use of temp table here 
... And then.. 

DROP TABLE #MyTempTable 

END 

이 SP 그래서 제 질문은 지금 여기 동시성 문제가 발생할 수있다, 매우 매우 자주 호출됩니다?

답변

28

아니요. 각 연결마다 임시 테이블의 독립 인스턴스가 작성됩니다.

+0

이 좋아 그게 내가 생각했던도 여기에 뭔가 END 할 및 임시 테이블을 구축하고 호출 할 수 있었다 - 가 을 시작하면서 PROC 노동자를 만들 나중에 내가 그것을 떨어 뜨리지 않았을 때 다시. 그러나 귀하의 게시물에 비추어 볼 때 새로운 쿼리를 열어 보았습니다. 성공하지 못했지만 지금은 다시 차분합니다. –

+0

그러나 성능에는 현저한 동시성 문제가 있습니다. – tpower

+1

@tpower : OP에 대한 제 이해는 주로 공유 상태 및 스레딩 문제 수정에 관한 것입니다. 성능이 영향을받는 것은 명백합니다. –

17

아마도.

접두사가 # (#example) 인 임시 테이블은 세션별로 유지됩니다. 따라서 다른 호출 (예 : 백그라운드 스레드)이 실행되는 동안 코드가 저장 프로 시저를 다시 호출하면 호출이 이미 있기 때문에 호출이 실패합니다. 당신이 정말로 테이블 변수를 사용하여 걱정하는 경우

대신

DECLARE @MyTempTable TABLE 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

이는 저장 프로 시저 호출의 "예"에 해당 될 것입니다.

+2

클라이언트가 수행하려는 작업과 상관없이 SQL 세션을 다시 사용할 수 없습니다. – gbn

+0

"(#example)은 세션 단위로 유지됩니다." 세션은 연결을 기반으로합니까? –

+0

그래, 그 명확한 gbn –

7

사실은 아니지만 SQL Server에 대해 이야기하고 있습니다. 임시 테이블 (단일 # 포함)이 존재하며 작성된 범위 내에서 볼 수 있습니다 (범위 바인딩 됨). 저장 프로 시저를 호출 할 때마다 새 범위가 만들어 지므로 temp 테이블은 해당 범위에만 존재합니다. temp 테이블은 스토어드 프로 시저 및 해당 범위 내에서 호출되는 udfs에서도 볼 수 있다고 생각합니다. 그러나 이중 파운드 (##)를 사용하면 세션 내에서 전역이되므로 임시 테이블이 생성되는 세션의 일부로 다른 실행 프로세스에서 볼 수 있으므로 임시 테이블에 액세스 할 수 있는지 생각해야합니다 동시에 바람직하다.

-1

데이터베이스는 모든 #temp 테이블에 대해 동일한 잠금을 사용하므로 많은 양을 사용하는 경우 교착 상태 문제가 발생합니다. 동시성을 위해 @ 테이블 변수를 사용하는 것이 더 좋습니다.

+1

-1 SQL Server 6.5 이후 잠금 문제가 발생하지 않았습니다. –

-1

가능하면 @temp 테이블을 사용하십시오. 즉, 기본 키가 하나만 필요하며 종속 저장된 proc의 데이터에 액세스 할 필요가 없습니다.

종속 저장된 프로 시저의 데이터에 액세스해야하는 경우 #temp 테이블을 사용하십시오 (저장된 proc 호출 체인의 악의있는 ​​전역 변수 임). 저장된 프로 시저간에 데이터를 전달하는 다른 방법이 없습니다. 보조 색인이 필요한 경우에도 사용하십시오 (둘 이상의 색인이 필요한 경우 # temp 테이블인지 직접 물어보십시오)

항상 상단에 #temp 테이블을 선언하십시오 함수의. SQL은 저장 프로 시저가 create table 문을 볼 때 강제로 재 컴파일합니다. 따라서 저장 프로 시저의 중간에 #temp 테이블 선언이 있으면 proc 저장 프로 시저가 처리를 중지하고 다시 컴파일해야합니다.

+1

-1 아니요, 임시 개체 (테이블 및 변수)는 일반적으로 SQL Server 2005 이상에서 캐시되므로 재 컴파일이 수행되지 않습니다. http://sqlblog.com/blogs/paul_white/archive/2012/08/17/temporary-object-caching-explained.aspx 및 http://technet.microsoft.com을 참조하십시오.com/ko-us/library/cc966545.aspx 예를 들어 –

0

SQL Server 2008 Books에 따라 로컬 및 글로벌 임시 테이블을 만들 수 있습니다. 로컬 임시 테이블은 현재 세션에서만 볼 수 있으며 전역 임시 테이블은 모든 세션에서 볼 수 있습니다.로컬 임시 테이블은 여러 사용자가 동시에 실행할 수있는 저장 프로 시저 또는 응용 프로그램에서 생성 된 경우

'#table_temporal

'## table_global

는 데이터베이스 엔진은 할 수 있어야합니다 서로 다른 사용자가 만든 테이블을 구별 할 수 있습니다. 데이터베이스 엔진은 각 로컬 임시 테이블 이름에 숫자 접미사를 내부적으로 추가하여이 작업을 수행합니다.

그런 다음 문제가 발생하지 않습니다.

2

테이블 변수를 사용하는 모든 권장 사항에 대해주의하십시오. 테이블 변수는 인덱싱 할 수 없지만 임시 테이블은 인덱싱 할 수 없습니다. 소량의 데이터로 작업 할 때 테이블 변수가 가장 적합하지만 더 큰 데이터 세트 (예 : 50k 레코드)로 작업하는 경우 임시 테이블은 테이블 변수보다 훨씬 빠릅니다.

try/catch를 사용하여 저장 프로 시저 내에서 강제로 정리를 수행 할 수는 없습니다. 작업자 저장 프로 시저의 try/catch를 수행 할 수있는 래퍼 저장 프로 시저를 만들 필요가있는 경우 특정 유형의 실패를 try/catch (예 : 지연된 이름 확인으로 인해 컴파일 실패)에서 발견 할 수 없습니다. 거기서 정리를해라.

내가 쿼리 분석기를 사용했기 때문에 신경 있어요 ..

create proc wrapper AS 
BEGIN 
    Create table #... 
    BEGIN TRY 
     exec worker 
     exec worker2 -- using same temp table 
     -- etc 
    END TRY 
    END CATCH 
     -- handle transaction cleanup here 
     drop table #... 
    END CATCH 
END