【发布时间】:2015-01-14 05:49:35
【问题描述】:
`
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 的表有超过3 条lacs 记录。表没有任何标识列,而是我根据唯一性在某些列的组上创建了聚集主索引。但是执行一个简单的选择语句仍然需要超过 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,
CONSTRAINT [PK_ParentFormResponses] 主键集群 ( [实体 ID] ASC, [FormId] ASC, [学生编号] ASC, [EntityTypeId] ASC, [表格版本] 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] 上`
=> 我删除了主键索引并在非聚集索引下创建
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
=> 基于 sp_spaceused 的所有三个表的结果是-
注意:记录数不是 30k 而是超过 3 lacs。不小心写错了。
【问题讨论】:
-
你知道什么是查询计划吗?如果没有 - 读取已完成。并张贴。也就是说,首先要实现 Distinct 盈余。这可能需要在 tempdb 上做很多工作,但是查询计划会告诉你。
-
从这么小的表中选择数据应该不会花很长时间。一定是提取过程花费了这么长时间。您是否存储大数据(图像、视频等)?我假设
select count(*) from ParentFormResponses只需要几秒钟。正确的?至于连接:您提到的 EntityId 和 EntityTypeId 上的索引通常应该很快,至少在有许多不同的 EntityId 时。 -
另一个问题:估计有多少用户在运行您的查询时访问表 ParentFormResponses?
-
发布查询计划 .. 还要确保您创建的非聚集索引实际正在使用并且统计信息是最新的..
-
尝试使用 group by 而不是 distinct
标签: sql sql-server