문제

다음과 같은 검색어가있는 경우 : 라코 디스

EmployeeTypeId 필드에 색인이 있습니다. SQL 서버가 해당 색인을 계속 사용합니까?

도움이 되었습니까?

해결책

예, 맞습니다.직원 테이블에 10,000 개의 레코드가 있고 5 개의 레코드 만 (1,2,3)에 employeetypeID가있는 경우 인덱스를 사용하여 레코드를 가져올 가능성이 높습니다.그러나 9,000 개의 레코드에 (1,2,3)에 employeeIDType이있는 것으로 확인되면 해당 EmployeeID를 얻기 위해 테이블 스캔을 수행 할 가능성이 큽니다.인덱스 트리의 각 분기를 확인하고 레코드를 개별적으로 살펴 봅니다.

SQL Server는 쿼리 실행 방법을 최적화하기 위해 많은 작업을 수행합니다.그러나 때로는 올바른 답을 얻지 못합니다.SQL Server가 인덱스를 사용하고 있지 않다는 것을 알고있는 경우 쿼리 분석기에서 실행 계획을 살펴보면 쿼리 엔진이 다음과 같이 쿼리를 변경하여 특정 인덱스를 사용하도록 지시 할 수 있습니다. 라코 디스

EmployeeTypeId 필드에있는 색인의 이름이 Index_EmployeeTypeId라고 가정합니다.

다른 팁

일반적으로 IN 절이 테이블의 너무 많은 부분을 다루지 않는 한 테이블 스캔을 수행합니다.특정 사례를 찾는 가장 좋은 방법은 쿼리 분석기에서 실행하고 실행 계획을 확인하는 것입니다.

늦게 상상할 수없는 방식으로 기술이 향상되지 않는 한 표시된 "IN"쿼리는 "IN"목록의 각 값에 대해 하나씩 세 개의 결과 집합을 OR-ing하는 결과를 생성합니다. . IN 절은 각 목록에 대한 동등 조건이되며 적절한 경우 색인을 사용합니다. 고유 ID와 충분히 큰 테이블의 경우 옵티마이 저가 인덱스를 사용하기를 기대합니다.

그러나 목록의 항목이 고유하지 않은 경우 "TypeId"가 외래 키인 것 같으면 배포에 더 관심이 있습니다. 옵티마이 저가 목록의 각 값에 대한 통계를 확인할지 궁금합니다. 첫 번째 값을 확인하고 행의 20 % (중요 할만큼 충분히 큰 테이블)에 있음을 발견했다고 가정합니다. 아마도 테이블 스캔 일 것입니다. 하지만 고유 한 경우에도 다른 두 가지에 대해 동일한 쿼리 계획이 사용됩니까?

아마 문제가 될 수 있습니다. Employee 테이블과 같은 것은 메모리에 캐시 된 상태로 유지 될만큼 충분히 작을 수 있으며 어쨌든 색인 된 검색과 그 차이를 알아 차리지 못할 것입니다.

그리고 마지막으로, 제가 설교하는 동안 IN 절의 쿼리를 조심하십시오. 이것은 종종 무언가가 작동하도록하는 빠른 방법이며 (적어도 저에게는) 요구 사항을 표현하는 좋은 방법이 될 수 있지만 거의 항상 조인으로 더 잘 재 작성되었습니다. 당신의 옵티마이 저는 이것을 발견 할만큼 똑똑 할 수도 있지만 다시는 그렇지 않을 수도 있습니다. 현재 프로덕션 데이터 볼륨에 대해 성능을 확인하지 않는 경우 그렇게하십시오. 요즘의 비용 기반 최적화에서는 전체로드와 대표 통계가있을 때까지 쿼리 계획을 확신 할 수 없습니다. 할 수 없다면 생산에서 놀라움에 대비하십시오 ...

<인용구>

따라서 "IN"절이 테이블 스캔을 실행할 가능성이 있지만 최적화 프로그램은 문제를 해결하는 가장 좋은 방법을 찾아 보시겠습니까?

인덱스 사용 여부는 테이블에있는 데이터의 유형 및 분포, 테이블 통계의 최신 상태, 실제 데이터 유형만큼 쿼리 유형에 따라 크게 달라지지 않습니다. 열의.

다음과 같은 경우 색인이 테이블 스캔에 사용된다는 다른 포스터는 정확합니다.

  • 쿼리는 색인 된 행의 특정 비율 이상에 액세스하지 않습니다 (예 : ~ 10 %이지만 DBMS마다 달라야 함).
  • 또는 행이 많지만 열에 고유 한 값이 상대적으로 적은 경우 테이블 스캔을 수행하는 것이 더 빠를 수도 있습니다.

    분명하지 않을 수있는 다른 변수는 비교되는 값의 데이터 유형이 동일한 지 확인하는 것입니다. PostgreSQL에서는 float로 필터링하지만 열이 int로 구성되어 있으면 인덱스가 사용되지 않을 것이라고 생각합니다. 인덱스 사용을 지원하지 않는 연산자도 있습니다 (다시 말하지만 PostgreSQL에서 ILIKE 연산자는 이와 같습니다).

    하지만 언급했듯이 의심스러운 경우에는 항상 쿼리 분석기를 확인하고 DBMS의 문서는 친구가됩니다.

@Mike : 자세한 분석에 감사드립니다.확실히 흥미로운 점이 몇 가지 있습니다.내가 게시 한 예는 다소 사소하지만 질문의 근거는 NHibernate를 사용하는 데 있습니다.

NHibernate를 사용하면 다음과 같은 절을 작성할 수 있습니다. 라코 디스

NHibernate는 다음과 같은 쿼리를 생성합니다. 라코 디스

당신과 다른 사람들이 지적했듯이 인덱스가 사용되거나 테이블 스캔이 발생할 때가있을 것 같지만 런타임까지 실제로 결정할 수 없습니다.

Select EmployeeId From Employee USE(INDEX(EmployeeTypeId))

This query will search using the index you have created. It works for me. Please do a try..

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top