如果你在使用CNBlogsDottext Beta2代码搭建BLOG站点,如果你的打开首页时每次都很慢,那就继续往下看。
~/AggSite/SiteCategory.ascx就是首页左边第二栏的“网站分类”控件,代码文件是~/AggSite/SiteCategory.ascx.cs。
http://wuchang.cnblogs.com
qq:3263262
现在来看看这个控件究竟是如何成为性能杀手的。
先来看看.ascx部分代码
![None.gif](/Images/OutliningIndicators/None.gif)
![dot.gif](/Images/dot.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![dot.gif](/Images/dot.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
注意绑定代码中使用了CheckTitle函数,接下来看看.cs 代码。
![None.gif](/Images/OutliningIndicators/None.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
在页面加载时调用了Config.GetSiteBlogConfigCollection()获取网站分类:
{
string dataFile = System.Web.HttpContext.Current.Server.MapPath( " ~/SiteBlogConfig.config " );
return (SiteBlogConfigCollection)Util.SerializationHelper.Load( typeof (SiteBlogConfigCollection),dataFile);
}
杀手1现形:
这里在每次首页加载的时候都要加载.config,然后返回反序列化得到的对象。众所周知序列化和反序列化性能是很低的,而这里每次页面加载都重复做一次,对性能的影响就不可不计了。
接下来看刚才提到的CheckTitle()方法:
{
if (Config.Settings.CategoryDepth == 2 )
{
return title;
}
SiteBlogConfig config = Config.GetSiteBlogConfigByCategoryID( int .Parse(CategoryID));
if (config != null )
{
title += string .Format( " ({0}/{1}) " ,GetRowsCount( true ,config).ToString(),GetRowsCount( false ,config).ToString());
}
return title;
}
这个方法返回的类似“最新评论区(0/21033) ”的字符串。
杀手2现形:
在这个方法中再次再现调用GetSiteBlogConfigByCategoryID() -> GetSiteBlogConfigCollection() ->GetSiteBlogConfigCollection()!这个方法可是在每次OnItemDataBound是都调用的呀,也就是说如果有10个网站分类,那么每次打开页面时在这里都重复10次反序列化"~/SiteBlogConfig.config"这个配置文件。
队此之外,这个访求中还2次调用GetRowsCount()方法,这个方法代码如下:
{
EntryQuery query = new EntryQuery();
query.PostType = PostType.BlogPost;
query.PostConfig = PostConfig.IsActive | PostConfig.IsAggregated;
if (IsToday)
{
DateTime now = DateTime.Now;
DateTime StartDate = new DateTime(now.Year,now.Month,now.Day, 0 , 0 , 0 , 0 );
query.StartDate = StartDate;
}
query = (EntryQuery)Dottext.Framework.Util.Globals.BuildEntryQuery(query,config);
return Entries.GetEntryCount(query);
}
此方法返回指定分类的文章数,如果IsToday=true,则只返回分类当天的文章数。最后一行调用
Entries.GetEntryCount(query);跟踪这个方法,在FrameWork项目Entries.cs中:{
return DTOProvider.Instance().GetEntryCount(query);
}
{
return GetReader( " blog_GenericGetEntriesCount_10 " ,EntryQueryParameters(query));
}
if ( @CategoryID is not null )
Begin
-- we will filter by categoryID. Should we also filter by date?
if ( @StartDate is null )
Begin
-- No Date Filter
SELECT
count (bc. [ ID ] ) as Count
FROM
blog_Content bc with (nolock)
INNER JOIN blog_Links bl with (nolock) on bc.ID = bl.PostID
INNER JOIN blog_Config bcc with (nolock) on bc.BlogID = bcc.BlogID and bcc.IsAggregated = 1
WHERE
bc.PostConfig & @PostConfig = @PostConfig
and bc.PostType | @PostType = @PostType
and bl.CategoryID = @CategoryID
End
Else
Begin
-- Filter by CategoryID and Date.
-- If we only have a start date and no stop date, add 24 hours to to stopdate
if ( @StartDate is not null and @StopDate is null )
Set @StopDate = DateAdd ( day , 1 , @StartDate )
-- No Date Filter
SELECT
count (bc. [ ID ] ) as Count
FROM
blog_Content bc with (nolock)
INNER JOIN blog_Links bl with (nolock) on bc.ID = bl.PostID
INNER JOIN blog_Config bcc with (nolock) on bc.BlogID = bcc.BlogID and bcc.IsAggregated = 1
WHERE
bc.PostConfig & @PostConfig = @PostConfig
and bc.PostType | @PostType = @PostType
and bl.CategoryID = @CategoryID
and bc.DateAdded >= @StartDate and bc.DateAdded <= @StopDate
End
End
杀手3现形
3个表的INNER JOIN查询,这可是每次打开页面时有网站分类数*2次调用的呀,以数据库的压力可想而知了,当文章数量越来越多的时候,你会发现每次打开首页数据库服务器的CPU曲线都有个飙升。
----------------------------------------------------
处理掉这个问题,打开首页时数据库服务器平静多了~~~
后话:
cnblogs并无这个现象,说明DUDU很早就已经发现这个问题。
希望此文能给使用cnblog代码的同志一点帮助。