답변:
평소와 마찬가지로 (대부분의 경우) 대답은 실행 계획에 있습니다.
행을 처리하고 다운 스트림으로 전달하기 전에 모든 행이 도착해야하는 특정 연산자가 있습니다. 예를 들면 다음과 같습니다.
이러한 이유로 인해 차단 또는 정지 및 이동 연산자라고하며, 옵티마이 저가 데이터를 찾기 위해 많은 양의 데이터를 처리해야한다고 생각할 때 종종 선택됩니다.
스트리밍을 시작하거나 발견 된 행을 즉시 전달할 수있는 다른 연산자가 있습니다.
쿼리가 데이터를 즉시 반환하기 시작하지만 즉시 완료되지 않는 경우 일반적으로 최적화 프로그램이 시작 비용이 낮은 연산자를 사용하여 일부 행을 빠르게 찾아 반환 할 계획을 선택했음을 나타냅니다.
이것은 사용자 또는 옵티마이 저가 도입 한 행 목표로 인해 발생할 수 있습니다.
SARGability 부족, 매개 변수 스니핑, 불충분 한 통계 등으로 인해 잘못된 계획을 선택한 경우에도 발생할 수 있지만 파악하는 데 더 많은 파기가 필요합니다.
자세한 내용은 Rob Farley의 블로그를 참조하십시오.
그리고 행 목표에 폴 화이트의 시리즈 여기 , 여기 , 여기 , 그리고 여기 .
SSMS에 대해 이야기하는 경우 행 버퍼가 채워지면 윌리 니 일뿐 만 아니라 행만 나타납니다.
관찰하고있는 내용을 이해하면 Management Studio에서 행을 렌더링 하는 방식 이며 SQL Server 가 행을 반환 하는 방식과는 거의 관련이 없습니다 . 실제로 큰 결과를 SSMS에 반환하고 그리드로 렌더링하려고하면 SSMS를 유지할 수없고 SQL Server가 앱에서 더 많은 행을 처리 할 때까지 기다리게됩니다. 이 경우 SQL Server 누적 ASYNC_NETWORK_IO
대기가 표시됩니다.
SSMS가 그리드를 그릴 때보 다 텍스트를 더 빨리 그릴 수 있기 때문에 Results to Grid 대신 Results to Text를 사용하여 다소 제어 할 수 있지만 열 수 및 관련 데이터 유형에 따라 가독성에 영향을 줄 수 있습니다. SSMS가 실제로 해당 창에 결과를 쓰려고 결정하면 출력 버퍼가 얼마나 꽉 찼는 지에 따라 영향을받습니다.
당신이있을 때 여러 개의 문을, 당신은 메시지 창에 출력 결과를 렌더링하는 버퍼를 강제하려면, 당신은 문 사이에 트릭을 인쇄 조금 사용할 수 있습니다 :
RAISERROR('', 0, 1) WITH NOWAIT;
그러나 이것은 모든 출력이 단일 명령문에서 오는 경우 SSMS가 행을 더 빨리 렌더링하도록 할 때 도움이되지 않습니다.
보다 직접적으로 SSMS에서 렌더링하는 결과 수를 제한하여 제어 할 수 있습니다. 나는 사람들이 그리드에 백만 개의 행을 반환하는 데 걸리는 시간에 대해 불평하는 경우가 종종 있습니다. SSMS 그리드에서 백만 개의 행으로 지구상의 모든 사람들이 할 일이 무엇인지 모르겠습니다.
와 같은 일부 해킹이 있습니다. OPTION (FAST 100)
첫 번째 100 행 (또는 외부가없는 경우 100 행)을 검색하는 데 최적화 ORDER BY
되지만 나머지 행에 대한 검색 속도가 훨씬 느려질 수 있습니다. 전체적으로 비효율적이므로 실제로는 IMHO 옵션이 아닙니다.
귀하의 질문은 SQLServer 자체에 관한 것이 아니라 다음과 같습니다.
이것을 제어하는 방법이 있습니까?
짧은 답변 :
sqlcmd
대신에 ssms
또는 sqlcmd
의 -modessms
긴 대답 :
당연하지! 하지만 한 - PROB
sqlcmd
또는 sqlcmd
-mode로 쿼리를 실행하십시오 .spid
세션 설정의 전체 목록을 얻습니다. sqlcmd
세션 설정과 비교하십시오 . 아무 것도 클릭하지 않으면 프로파일 러의 모든 세션 설정을 쿼리 스크립트로 복사하고 sqlcmd
-mode 에서 실행 하고 점차적으로 설정을 변경하면 범인을 찾을 수 있습니다.행운을 빕니다!
sp_BlitzErik의 답변에 추가하려면 NOT IN ()
하위 선택과 함께 a 를 사용하여 예를 들어보십시오 . 항목이 중첩 쿼리의 결과인지 여부를 확인하려면 (일반적으로) 전체 결과를 검색해야합니다.
따라서 이러한 쿼리의 성능을 향상시키는 쉬운 방법 중 하나는 side LEFT OUTER JOIN
조건 RIGHT
이 null 인 곳 으로 다시 작성하는 것 입니다 (물론 뒤집을 수는 있지만 누가 RIGHT OUTER JOINS
? 를 사용 합니까). 이를 통해 결과가 즉시 반환됩니다.
WHERE t.x IN (<complex SELECT subquery>)
동등한 LEFT JOIN을 확인하기 전에 전체 부속 선택을 평가해야하는 실제 복잡한 선택 인 경우 부속 조회도 평가해야합니다 ( LEFT JOIN (<complex SELECT subquery>) AS r ON r.x = t.x .... WHERE r.x IS NULL
NO와 동일한 복잡한 계획 IN 버전).
NOT EXISTS
되었지만 NOT IN
쿼리 에서는 Oracle 이 선호 되었습니다. 그러나 오늘날 계획 생성기에서 오류로 간주되어야합니다.