【发布时间】:2010-12-07 14:34:36
【问题描述】:
我们有一个查询和this is an actual execution plan
如您所见 - Clustered Index Seek 占用 99%。 它还寻找主键(类型 int)。
表来源有 275 000 行。
表 AuthorSource 有 2 275 000 行。
不使用分区和压缩。
问题是第一次执行需要 25-40 秒。但是第二次运行连续需要1-2秒。
我们还在此服务器上运行复制、队列读取器、日志读取器代理。
内存量:4GB
Sql Server 使用:3.7GB
我们认为,sql 在第一次执行后缓存查询一段时间,这就是第二次运行只需要 1-2 秒的原因。
但是不管缓存等原因,很奇怪,主键索引查找查询需要20-40秒。
重复此问题。我们为查询提供的任何不同参数 - 我们都会得到相同的结果:第一次查询很长,第二次查询速度很快。
可能是我们必须使用的一些额外设置或资源管理器能力?
exec sp_executesql N'
SELECT [Project1].[C1] AS [C1]
FROM ( SELECT CAST(1 AS bit) AS X
) AS [SingleRowTable1]
LEFT OUTER JOIN
(SELECT [GroupBy1].[A1] AS [C1]
FROM ( SELECT COUNT(CAST(1 AS bit)) AS [A1]
FROM (SELECT [Extent1].[Mention_ID] AS [Mention_ID] ,
[Extent1].[Theme_ID] AS [Theme_ID] ,
[Extent1].[Mention_Weight] AS [Mention_Weight] ,
[Extent1].[AuthorSource_ID] AS [AuthorSource_ID1] ,
[Extent1].[Mention_CreationDate] AS [Mention_CreationDate] ,
[Extent1].[Mention_DeletedMark] AS [Mention_DeletedMark] ,
[Extent1].[Mention_AuthorTags] AS [Mention_AuthorTags] ,
[Extent1].[Mention_Tonality] AS [Mention_Tonality] ,
[Extent1].[Mention_Comment] AS [Mention_Comment] ,
[Extent1].[Mention_AdditionDate] AS [Mention_AdditionDate] ,
[Extent1].[UserToAnswer_ID] AS [UserToAnswer_ID] ,
[Extent1].[GeoName_ID] AS [GeoName_ID] ,
[Extent1].[Geo_ID] AS [Geo_ID] ,
[Extent1].[Mention_PermaLinkHash] AS [Mention_PermaLinkHash] ,
[Extent1].[Mention_IsFiltredByAuthor] AS [Mention_IsFiltredByAuthor] ,
[Extent1].[Mention_IsFiltredByGeo] AS [Mention_IsFiltredByGeo] ,
[Extent1].[Mention_IsFiltredBySource] AS [Mention_IsFiltredBySource] ,
[Extent1].[Mention_IsFiltredBySourceType] AS [Mention_IsFiltredBySourceType] ,
[Extent1].[GengineLog_InstanceId] AS [GengineLog_InstanceId] ,
[Extent1].[Mention_PermaLinkBinaryHash] AS [Mention_PermaLinkBinaryHash] ,
[Extent1].[Mention_APIType] AS [Mention_APIType] ,
[Extent1].[Mention_IsFilteredByAuthorSource] AS [Mention_IsFilteredByAuthorSource],
[Extent1].[Mention_IsFavorite] AS [Mention_IsFavorite] ,
[Extent1].[Mention_SpamType] AS [Mention_SpamType] ,
[Extent1].[MentionContent_ID] AS [MentionContent_ID] ,
[Extent2].[AuthorSource_ID] AS [AuthorSource_ID2] ,
[Extent2].[Author_ID] AS [Author_ID] ,
[Extent2].[Source_ID] AS [Source_ID] ,
[Extent2].[Author_Nick] AS [Author_Nick] ,
[Extent2].[Author_UrlBinaryHash] AS [Author_UrlBinaryHash] ,
[Extent2].[AuthorSource_Type] AS [AuthorSource_Type] ,
[Extent2].[Author_Url] AS [Author_Url] ,
[Extent2].[AuthorSource_Description] AS [AuthorSource_Description] ,
[Extent2].[AuthorSource_Gender] AS [AuthorSource_Gender]
FROM [dbo].[Mention] AS [Extent1]
LEFT OUTER JOIN [dbo].[AuthorSource] AS [Extent2]
ON [Extent1].[AuthorSource_ID] = [Extent2].[AuthorSource_ID]
WHERE (
[Extent1].[Mention_DeletedMark] <> CAST(1 AS bit)
)
AND
(
[Extent1].[Mention_IsFiltredByAuthor] <> CAST(1 AS bit)
)
AND
(
[Extent1].[Mention_IsFilteredByAuthorSource] <> CAST(1 AS bit)
)
AND
(
[Extent1].[Mention_IsFiltredByGeo] <> CAST(1 AS bit)
)
AND
(
[Extent1].[Mention_IsFiltredBySource] <> CAST(1 AS bit)
)
AND
(
[Extent1].[Mention_IsFiltredBySourceType] <> CAST(1 AS bit)
)
) AS [Filter1]
LEFT OUTER JOIN [dbo].[Source] AS [Extent3]
ON [Filter1].[Source_ID] = [Extent3].[Source_ID]
WHERE (
[Filter1].[Theme_ID] = @p__linq__49557
)
AND
(
[Extent3].[Source_Type] <> @p__linq__49558
)
) AS [GroupaBy1]
) AS [Project1]
ON 1 = 1
',N'@p__linq__49557 int,@p__linq__49558 int',@p__linq__49557=7966,@p__linq__49558=8
IndexSeeking Performance Information
我们还用这个简单的代码在 sql 中手动编写查询:
Select COUNT(1) from Mention m inner join AuthorSource auth on m.AuthorSource_ID = auth.AuthorSource_ID inner join
Source s on auth.Source_ID = s.Source_ID where
m.Mention_DeletedMark = 0 AND m.Mention_IsFilteredByAuthorSource = 0 AND m.Mention_IsFiltredByAuthor = 0
AND m.Mention_IsFiltredByGeo = 0 AND m.Mention_IsFiltredBySource = 0 AND m.Mention_IsFiltredBySourceType = 0
AND m.Theme_ID = 7966
and s.Source_Type <> 8
执行计划与我们发布的相同。
【问题讨论】:
-
请同时发布查询。
-
你能在不改变查询语义的情况下将所有
<> CAST(1 AS bit)更改为= CAST(0 AS bit)吗?这些列可以为空吗? -
@mmcteam.com.ua - 你正在寻找。不确定嵌套循环是否是此行数的最佳连接策略。对于您的性能观察,最可能的解释是它第一次运行时需要执行大量物理 i/o,并且在随后的执行中,页面位于缓冲区缓存中。你可以试试
SET STATISTICS IO ON和SET STATISTICS TIME ON吗? -
您可以通过查看反复使用
CHECKPOINT; DBCC DROPCLEANBUFFERS清除缓存是否会导致问题再次出现来确定。显然,最好在开发服务器上进行测试! -
在您发布的查询中,将两个
inner join更改为inner hash join会使事情变得更好还是更糟?
标签: sql sql-server sql-server-2008