다음 테스트를 통해 검증한 결과, 먼저 데이터 분포가 고르지 않은 테스트 테이블을 생성합니다.
USE tempdb GOCREATE TABLE _t( c varchar(50) );CREATE INDEX IX_c ON _t( c );GO-- 加入 10000 条数据INSERT _tSELECT (9999 + id) FROM( SELECT TOP 10000 id = ROW_NUMBER() OVER( ORDER BY GETDATE() ) FROM sys.all_columns a, sys.all_columns )ID -- 将 100 - 10000 的数据变成相同值UPDATE _t SET c = '' WHERE c >= '10100'
그런 다음 varhcar 및 nvarchar 값을 사용하여 각각 1개 조건과 8900개 조건을 충족하는 실행 계획 행의 예상 개수를 테스트합니다.
ALTER INDEX IX_c ON _t REBUILD;GOSET SHOWPLAN_ALL ONGOSELECT * FROM _t WHERE c = '10005'; -- 实际1条GOSET SHOWPLAN_ALL OFF;GOALTER INDEX IX_c ON _t REBUILD;GOSET SHOWPLAN_ALL ONGOSELECT * FROM _t WHERE c = N'10005'; -- 实际1条GOSET SHOWPLAN_ALL OFF;GOALTER INDEX IX_c ON _t REBUILD;GOSET SHOWPLAN_ALL ONGOSELECT * FROM _t WHERE c = ''; -- 实际9900条GOSET SHOWPLAN_ALL OFF;GOALTER INDEX IX_c ON _t REBUILD;GOSET SHOWPLAN_ALL ONGOSELECT * FROM _t WHERE c = N''; -- 实际9900条GOSET SHOWPLAN_ALL OFF;GO
얻은 쿼리 계획의 예상 행 수는 아래 그림과 같습니다.
그림에 표시된 예상 데이터 행 수에서 varchar 값에 대해 알 수 있습니다(숨겨진 데이터 없음). 타입 변환이 필요함), 추정 행 수는 추정 결과가 정확합니다. 그러나 nvarchar 값의 경우 지정된 값에 데이터가 한 개만 있거나 8900개의 데이터가 일치하는지 여부에 관계없이 추정 결과는 99.0099로, 이는 우리가 지정한 값을 고려하지 않고 추정되었음을 나타냅니다.
변수를 사용한 추가 테스트
ALTER INDEX IX_c ON _t REBUILD;GOSET SHOWPLAN_ALL ONGODECLARE @v varchar;SELECT * FROM _t WHERE c = @v; -- varcharGOSET SHOWPLAN_ALL OFF;GOALTER INDEX IX_c ON _t REBUILD;GOSET SHOWPLAN_ALL ONGODECLARE @nv nvarchar;SELECT * FROM _t WHERE c = @nv; -- nvarcharGOSET SHOWPLAN_ALL OFF;GO
결과는 아래 그림과 같습니다.
varchar 변수든 nvarchar 변수든 예상 행 수는 99.0099입니다. nvarchar 상수 값입니다. SQL Server 쿼리 최적화 프로그램은 실제로 GetRangeThroughConvert의 결과를 변수로 간주해야 합니다. 이는 결국 고정된 상수 값이 지정된 경우 GetRangeThroughConvert의 결과도 특정해야 한다는 점을 제대로 고려하지 않은 설계입니다. 값.
이 기사에서는 SQL Server 관련 내용을 설명합니다. 더 많은 관련 내용을 보려면 PHP 중국어 웹사이트를 참고하세요.
관련 권장 사항:
MySQL에서 단일 문장으로 무한 수준의 부모-자식 관계 쿼리를 구현하는 방법
진행 상태로 SQL Server FileStream에 액세스하는 방법
잊은 경우 수행할 작업 SQL Server 관리자 비밀번호
위 내용은 실행 계획의 암시적 데이터 형식 변환 처리에 대한 SQL Server 2008 개선 사항의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!