2014-11-17 2 views
1

`쿼리 및 테이블 최적화

SELECT DISTINCT ECS.UserId,,PFR.EntityId,PFR.CreatedBy 
FROM EventConsentStatus ECS 
INNER JOIN @Institutions I ON ECS.InstitutionId=I.InstitutionId    
LEFT JOIN ParentFormResponses PFR ON PFR.EntityTypeId = 1 
      AND [email protected] AND ECS.EventId=PFR.EntityId     
WHERE ECS.EventId = @ActivityId 

테이블 위의 쿼리에서 언급 한 ParentFormResponses라고는 3lacs 기록보다 더 가지고있다. 테이블 대신 고유 ID를 기반으로 일부 열 그룹의 클러스터 된 기본 인덱스를 만들었습니다. 그러나 간단한 선택 진술 문을 실행하는 데는 여전히 16 분 이상 걸립니다. 즉 select * from ParentFormResponses입니다.

위에서 언급 한 select 문에서 ParentFormResponses 테이블의 열 이름을 제거 할 경우 2 3 초가 걸릴 것이지만 위 쿼리의 경우 너무 많은 시간이 걸립니다.

entityid에 클러스터되지 않은 색인을 만들고 entitytypeid를 작성하면 최적화 된 결과를 얻지 못합니다.

어떻게 테이블 구조와 쿼리 성능을 향상시킬 수 있는지 제안 해주십시오.

자세한 정보를 표 Stucture :

`CREATE TABLE [dbo].[ParentFormResponses](
[EntityId] [int] NOT NULL, 
[FormId] [int] NOT NULL, 
[StudentId] [nvarchar](50) NOT NULL, 
[CreatedBy] [nvarchar](50) NOT NULL, 
[CreatedOn] [datetime] NOT NULL, 
[EntityTypeId] [int] NOT NULL, 
[FormVersion] [decimal](18, 1) NOT NULL, 
[DigitallySigned] [bit] NULL, 
[HasResponseChanged] [bit] NULL, 

CONSTRAINT [PK_ParentFormResponses] ( [ENTITYID] ASC, [FormId] ASC, [StudentId] ASC 클러스터형 PRIMARY KEY [EntityTypeId ], [FormVersion] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY][PRIMARY] 'I 떨어

=> 기본 키 인덱스 ON) 및

입었네 sp_spaceused를 기반으로 세 테이블 클러스터되지 않은 인덱스 CREATE NONCLUSTERED INDEX [IX_ParentFormResponses_sakshi_EntityId] ON [dbo].[ParentFormResponses_sakshi] ( [EntityId] ASC, [EntityTypeId] ASC, [FormId] ASC, [FormVersion] ASC ) INCLUDE ( [StudentId], [CreatedBy]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO

=> 결과 아래에 만들어진

  • 이름 행, 예약, 데이터, 인덱스 크기, 사용되지 않음
  • ParentFormResponses - 309961, 64704 KB, 63592 KB, 936 KB, 176 KB
  • ParentFormResponses_sakshi- 309893, 117,696킬로바이트, 60,472킬로바이트, 56,944킬로바이트, 2백80킬로바이트
  • EventConsentStatus - 673796, 380,920킬로바이트, 109,240킬로바이트, 271,512킬로바이트, 168킬로바이트
  • 것은 참고 : 레코드 수는 없습니다 30K 그러나보다 더 있습니다 3 lacs. 실수로 나는 잘못 썼다.

    +0

    쿼리 계획이 무엇인지 알고 계십니까? 그렇지 않다면 - 읽기가 끝났습니다. 그리고 그것을 게시하십시오. 그렇다면 Distinct 잉여를 만드는 것으로 시작하십시오. tempdb에서 많은 작업이 필요할 수 있지만 쿼리 계획에서 알려줍니다. – TomTom

    +0

    작은 테이블에서 데이터를 선택하려면 오래 걸리지 않습니다. 너무 오랜 세월이 걸리는 페칭 절차가 있어야합니다. 큰 데이터 (이미지, 비디오 등)를 저장하고 있습니까? ''ParentFormResponses에서 셀렉트 (count) (*) '를 선택하는 데는 몇 초 밖에 걸리지 않습니다. 옳은? 조인과 관련하여 EntityId 및 EntityTypeId에 ​​대한 인덱스는 적어도 다른 EntityId가있을 때 일반적으로 이렇게 빨리 작성해야합니다. –

    +0

    또 다른 질문 : 추정치, 쿼리를 실행할 때 얼마나 많은 사용자가 테이블 ParentFormResponses에 액세스합니까? –

    답변

    1

    distinctleft join의 조합은 성능 측면에서 의심 스럽습니다. 먼저 다음 쿼리를 확인하십시오.

    SELECT ECS.UserId, ECS.EntityId 
    FROM EventConsentStatus ECS INNER JOIN 
        @Institutions I 
        ON ECS.InstitutionId = I.InstitutionId    
    WHERE ECS.EventId = @ActivityId; 
    

    인덱스를 EventConsentStatus(EventId, UserId)에 최적화 할 수 있습니다. 이것은 좋은 성능을 가지고 있다고 가정하고, 올바른 행 집합을 생성합니다. 그렇지 않다면 @Institions에서 복제본을 가져올 수 있습니다. 이 경우 해당 테이블을 제거하는 것이 좋습니다 (해당 테이블에서 사용되는 열은 필터링 용으로 만 사용됨).또는 :

    SELECT ECS.UserId, ECS.EntityId 
    FROM EventConsentStatus ECS 
    WHERE ECS.EventId = @ActivityId AND 
         EXISTS (SELECT 1 FROM @Institutions I WHERE ECS.InstitutionId = I.InstitutionId) 
    

    오른쪽 값을 가져 오려면의이 outer apply를 사용하여 추가 데이터를 얻을 수 있도록이 들어

    SELECT ECS.UserId, PFR.EntityId, PFR.CreatedBy 
    FROM EventConsentStatus ECS INNER JOIN 
        @Institutions I 
        ON ECS.InstitutionId = I.InstitutionId OUTER APPLY 
        (SELECT TOP 1 PFR.EntityId, PFR.CreatedBy 
         FROM ParentFormResponses pfr 
         WHERE ECS.EventId = PFR.EntityId AND 
          PFR.EntityTypeId = 1 AND 
          PFR.EntityId = @ActivityId 
        ) pfr 
    WHERE ECS.EventId = @ActivityId; 
    

    , 당신이 ParentFormResponses(EntityId, EntityTypeID, CreatedBy)에 인덱스를 원한다.

    +0

    나는 적절한 색인으로 외부 적용을 시도했지만 여전히 너무 많은 시간을 보냈습니다. 두 쿼리를 모두 실행하면 Outer 내부의 쿼리와 다른 쿼리가 별도로 실행되므로 몇 초 밖에 걸리지 않습니다. 그러나 왼쪽 조인 또는 외부 적용은 최적화 된 결과를 제공하지 않습니다. – Sakshi

    +0

    @Sakshi. . . 방금 색인 정의를 업데이트했습니다. 인덱스와 퍼포먼스에 영향을주는 상관 관계가있는 'join'조건을 잘못 읽었습니다. –