在我的应用程序中,我有产品和类别。产品可以是多个类别。所以我有两个表:CwObject(产品)和EntityObjectLink(产品和类别之间的链接)。我有一个经常使用的查询,但即使经过几天的调整,它也非常慢。在CwObject中有大约400K的记录,在EntityObjectLink中有大约1.2M的记录。
这是查询:
SELECT TOP (99999)
CwObject.*
FROM
CwObject
INNER JOIN
dbo.EntityObjectLink ON CwObject.CwObject_Guid = EntityObjectLink.EntityObjectLink_LinkedCwObject_Guid
WHERE
EntityObjectLink_LinkedCwEntity_Guid = '9a0e41d7-a472-445e-b94f-44fe1a1506b3'
AND CwObject_CwSiteCluster_Guid = '0f178176-9720-41c7-9528-99fdf30005e8'
AND CwObject_EntityType = 1
AND (CwObject_Predecessor_Guid IS NULL)
ORDER BY
CwObject_Name ASC
EntityObjectLink
有一个相关的聚集索引:
PRIMARY KEY CLUSTERED ([EntityObjectLink_LinkedCwEntity_Guid] ASC,
[EntityObjectLink_LinkedCwObject_Guid] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
CwObject
表有一个相关索引:
NONCLUSTERED INDEX [IX_ClusterEntitytypePredecessorStatusClusteraccount]
ON [dbo].[CwObject]([CwObject_CwSiteCluster_Guid] ASC,
[CwObject_EntityType] ASC,
[CwObject_Predecessor_Guid] ASC,
[CwObject_Status] ASC,
[CwObject_ClusterAccount_Guid] ASC)
INCLUDE (% ALL other columns%)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
如果我使用查询优化器,它告诉我查询使用两个索引。但我看到了一些我不明白的事情:
它警告我没有实体类型和predecessorguid的列统计信息。可能是因为我刚刚添加了索引吗?
CwObjects
表上的实际和估计行读取之间存在巨大差异。
如果我查看实时查询统计信息,查询会在CwObjects
中读取带有索引搜索的171K记录(为什么要搜索?)。然后在EntityObjectLink
表上进行合并连接,其中读取2.5K记录。以相反的方式做它会更有效。
我真的,真的被困在这里......任何人都可以帮忙吗?
以下是执行计划:https://1drv.ms/u/s!AlCbN2sexrJ-hNJjeSR9cZPOEpOHww
更新:
AtoStats开启,几个小时。
几乎所有时间都在CwObject索引中消耗......
更新2:
我强制统计信息在cwObjects
表上更新。这产生了巨大的差异!查询速度快了近10倍!
答案 0 :(得分:4)
您没有关于某些列的统计信息,因此您会在执行计划中收到此警告:
没有统计数据的列: 。[compareware] [DBO] [CwObject] .CwObject_EntityType; [compareware] [DBO]。[CwObject] .CwObject_Predecessor_Guid
这导致实际行数为174480,而估计行数为1779,2。
尝试激活数据库上的auto create statistics
,或手动创建这些列的统计信息。