`
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 PFR.EntityId=@ActivityId AND ECS.EventId=PFR.EntityId
WHERE ECS.EventId = @ActivityId在上面的查询中提到的一个名为ParentFormResponses的表有超过3lacs的记录。表中没有任何标识列,相反,我已经根据唯一性在某些列的组上创建了聚集主索引。但是,执行一个简单的select语句需要超过16分钟,即select * from ParentFormResponses。
如果我要从上面提到的select语句中删除ParentFormResponses表的列名,那么它将在2-3秒内显示结果,但是对于上面的查询,需要花费太多的时间。
如果我在entityid和entitytypeid上创建非聚集索引,那么它也没有给出优化结果。
请建议我如何改进表结构和查询性能。
详细信息:表结构:
`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,PRIMARY上的约束PK_ParentFormResponses主键群集( EntityId ASC、FormId ASC、StudentId ASC、EntityTypeId ASC、FormVersion ASC )与(PAD_INDEX = OFF、STATISTICS_NORECOMPUTE = OFF、IGNORE_DUP_KEY = OFF、ALLOW_ROW_LOCKS = ON、ALLOW_PAGE_LOCKS = ON、FILLFACTOR = 90)在PRIMARY上进行
=> i删除主键索引并在非聚集索引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下面创建
基于=>的所有三个表的结果如下-
注意:记录的数量不是30k,而是3个以上的记录。我写错了。
发布于 2014-11-17 12:40:04
从性能角度来看,distinct和left 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)上的索引。
https://stackoverflow.com/questions/26970621
复制相似问题