2010-06-15 3 views
0

조회 테이블 (##lookup)이 있습니다. 나는 데이터를 복제하기 때문에 나쁜 디자인이라는 것을 알고 있지만, 그것은 내 쿼리를 엄청나게 빠르게한다. 이 명확하게 제대로 테이블을 업데이트쿼리에서 제외 위치

delete from ##lookup 
insert into ##lookup select distinct col1,col2,... from table1...join...etc... 

:이 표는이 동작을 시뮬레이션하고 싶은

insert into ##lookup select distinct col1,col2,... from table1...join...etc... 

에게 웁니다 쿼리가 있습니다. 그러나 이것은 많은 삽입 및 삭제입니다. 그것은 내 색인을 망쳐 놓고 선택할 테이블을 잠급니다. 더 오래 걸릴 수 있습니다

delete from ##lookup where not in (select distinct col1,col2,... from table1...join...etc...) 
insert into ##lookup (select distinct col1,col2,... from table1...join...etc...) except if it is already in the table 

두 번째 방법은, 그러나 나는 "아니오 잠금"말할 수와 나는 테이블에서 선택할 수 있습니다 :

이 테이블

도 같은 업데이트 할 수 있습니다.

두 번째 방법으로 쿼리를 작성하는 방법에 대한 아이디어가 있습니까?

답변

2
DELETE LU 
FROM ##lookup LU 
LEFT OUTER JOIN Table1 T1 ON T1.my_pk = LU.my_pk 
WHERE T1.my_pk IS NULL 

INSERT INTO ##lookup (my_pk, col1, col2...) 
SELECT T1.my_pk, T1.col1, T1.col2... 
FROM Table1 T1 
LEFT OUTER JOIN ##lookup LU ON LU.my_pk = T1.my_pk 
WHERE LU.my_pk IS NULL 

위의 LEFT JOIN 대신 WHERE NOT EXISTS를 사용하여 행이 존재하지 않는 것을 찾을 수도 있습니다.

SQL 2008을 사용하는 경우 MERGE 문을 살펴보아야 할 수도 있습니다. 그렇지 않으면 테이블을 동기화 상태로 유지하지 않고 PK 만 동기화합니다. 하나의 테이블에서 열 중 하나가 변경되었지만 위에 반영되지 않는 다른 열은 변경되지 않습니다.

어느 쪽이든, 질문을 최적화하는 것이 좋습니다. 데이터 복제는 성능 문제를 해결하는 데 도움이되는 것처럼 보일 수 있습니다. 볼 수 있듯이 많은 두통을 겪을 수 있습니다 (단 하나뿐입니다). 빈약 한 성능의 근원적 인 원인을 찾아내는 것이 더 낫습니다.

+0

ya 잘 이상적인 솔루션은 SQL 서버에서 호출 할 때 "meterialized veiw"또는 인덱싱 된 뷰를 사용하는 것입니다. 그러나 뷰를 인덱싱하려면이 경우 자체 조인을 사용하지 않아야합니다.자가 조인은 심지어 기술적으로 자체 조인이 아닌 경우 조인에서 동일한 테이블을 두 번 사용하는 것을 포함합니다. 따라서 최적이 될 수있는 옵션을 사용할 수 없습니다. 나를 믿어 라. 나와 나보다 훨씬 더 똑똑한 몇 사람은 더 나은 해결책을 찾기 위해 많은 시간을 투자했다. 소스 테이블을 죽음으로 인덱싱하는 것은 지금까지 우리에게 달렸고 질의를 최적화 할 수는 없었습니다 ... – kralco626

+0

하지만 전적으로 당신과 동의합니다. 이것은 엿 같은 해결책입니다 ...Microsoft 만이보기를 사용하도록 허용하는 경우 ... 내 문제의 해결 방법이 있지만 알아 내기가 너무 복잡합니다. 나는 그것에 관하여 질문을 여기에서 물었다 : http://stackoverflow.com/questions/3046058/need-some-serious-help-with-self-join-issue 그 문제점이 해결되면 나는 이것을 할 필요 없다. – kralco626

0

전체 테이블을 핵으로 만들 계획이라면 성능을 저하시키는 모든 삭제가 기록됩니다. 처리중인 행 수에 따라 로그되지 않은 TRUNCATE 만 사용해도됩니다.

SELECT 문은 어느 정도 걸립니까? 선택에 약간의 시간이 걸리고 자주 실행하지 않는 경우 이와 같은 것을 시도 할 수 있습니다.

tempTable1 #에서 ## 조회에 ## 조회 선택 * 거래를 드롭 테이블을 시작 ... 등 ... 가입 ... 표 1에서 # tempTable1 ... INTO 을 별개의 선택

트랜잭션을 처리하십시오.

Tom의 대답은 아마도 가장 강력 할 것 같지만, 저는 방금 몇 가지 대안으로 차임 할 것이라고 생각했습니다. 왜 글로벌 임시 테이블이 실제 테이블과 비교하여 필요한지 잘 모르겠습니까?

+0

나중에 나는 데이터베이스에 실제 테이블을 만들 권한이 없습니다. 그래서 나는 내가 원하는 것을 알아낼 때까지는 임시 직원으로 놀고 그 다음 실제 테이블을 만드는 것에 대해 생각합니다. 그래서 실제로 이것이 실제로 사용될 때, 나는 실제 테이블을 사용할 것이고, 나는 테이블을 떨어 뜨릴 수 없을 것입니다 ... – kralco626