优化你的DiscuzNT 让它跑起来

  • 时间:
  • 浏览:0
  • 来源:大发uu快3_uu快3人工计划_大发uu快3人工计划

  去年用DiscuzNT3.0做过二次开发,做过有些性能优化,但会 时间关系老是没从前写下来;趁着5.1长假,来写篇回忆性的随笔吧。

  从前看到园子里代震军同学的博客,知道了老代同学学DiscuzNT团队的一员,从他的博文学了不少东西,我这里写的博文是针对有些什么的现象提出当事人的看发和解决方案,针对什么的现象并无针对任何人之意,秉着技术交流的原则。

  DiscuzNT给我的印象是

  1)功能很强大,所遇见你能想到的基本都从前有了;

  2)性能有待优化,数据量较大的情况报告会产生性能瓶颈(这也正是写此文的目的)。从前发的博文从前缺陷经验,没有足够的论据,今天会多提供些图文并茂的论据。

  好了,言归正转,开始大伙儿 今天的优化之旅。

  本系统环境如下:

  软件环境:DiscuzNT3.0,sqlserver30000,windwos server30003

  数据环境:主贴表dnt_topics约220万条记录,回复表十个 ,dnt_posts1约300万,dnt_posts2约30000万,dnt_posts3约30000万,附件表约170万,用户表dnt_users约20万,论坛表dnt_forums约300000个论坛;

  什么的现象:看帖时,从前帖子中有 附件,会很卡;

  目的:优化看帖波特率,尤其是有附件的情况报告

  动手:看下它是何如获取附件的,找到showtopic.aspx.cs,代码如下:

postlist = Posts.GetPostList(postpramsInfo, out attachmentlist, ismoder == 1); 

  再看下 Posts.GetPostList() 法律最好的办法的代码: 

 /// <summary>

/// 获取指定条件的帖子DataSet

/// </summary>

/// <param name="_postpramsinfo">参数列表</param>

/// <returns>指定条件的帖子DataSet</returns>

public static List<ShowtopicPagePostInfo> GetPostList(PostpramsInfo postpramsInfo, out List<ShowtopicPageAttachmentInfo> attachList, bool isModer)

{

List<ShowtopicPagePostInfo> postList = Data.Posts.GetPostList(postpramsInfo);

int adCount = Advertisements.GetInPostAdCount("", postpramsInfo.Fid);

foreach (ShowtopicPagePostInfo postInfo in postList)



{

LoadExtraPostInfo(postInfo, adCount);

}

attachList = new List<ShowtopicPageAttachmentInfo>();

if (postList.Count == 0)

return postList;

string pidList = GetPidListWithAttach(postList);



attachList = Attachments.GetAttachmentList(postpramsInfo, pidList);

ParsePostListExtraInfo(postpramsInfo, attachList, isModer, postList);

return postList;

  从这可不可不还都可以 能看出,DiscuzNT是把所有的帖子id组装成“id1,id2,id3,id4”的形式,但会 传入数据库,解决多次调用数据库,你你这一 思路很好,现在大伙儿 顺藤摸瓜,看看它调用了数据库的脚本,它调用了你你这一 过程dnt_getattachmentlistbypid,用profiler跟踪你你这一 过程看看性能。

  看后边的图,execdnt_getattachmentlistbypid@pidlist='5163797'你你这一 脚本的cpu=4531,reads=152641,duration=6156,很可观吧,从前一齐有10当事人来调用你你这一 过程,估计数据库的压力就大了,从前3000人,难以想象。从前们为什么来优化你你这一 过程呢,先看看后边它为什么写的,否有用到了索引。

ALTER   PROCEDURE [dnt_getattachmentlistbypid]

@pidlist varchar(30000)

AS

SELECT

[aid],

[uid],

[tid],

[pid],

[postdatetime],

[readperm],

[filename],

[description],

[filetype],

[filesize],

[attachment],

[downloads],

[attachprice],

[width],

[height]

FROM [dnt_attachments]

WHERE CHARINDEX(','+RTRIM([dnt_attachments].[pid])+',', ','+@pidlist+',')>0

  这里主要查找的条件是pid,从前在pid列上建立索引,但会 过程能用到索引,效果应该会更理想,你你这一 优化工作我分为如下几步:

  1)pid列上否有有索引;

  2)过程否有用到了索引;

  3)优化sql脚本;

  4)跟踪优化后效果;

  大伙儿 一步有一个多 坑往下走:

  1)sp_helpindexdnt_attachments看看否有有索引,如下图,从图中可不可不还都可以 看到pid列上是有索引的,从前没有索引,请建立相关索引

  2)看看否有用到了索引,CTRL+L看看下面句子的执行计划,他用到的索引是PK_dnt_attachments,根本没用到大伙儿 期望的pid

  3)没用到大伙儿 期望的索引,从前们就来优化一下;后边的dnt_getattachmentlistbypid过程后边WHERECHARINDEX(','+RTRIM([dnt_attachments].[pid])+',',','+@pidlist+',')>0对pid进行了列运算,你你这一 是罪魁祸首,大伙儿 想法律最好的办法把你你这一 列运算再加,你你这一 过程最终改成下面你你这一 样子:

ALTER    PROCEDURE [dnt_getattachmentlistbypid]

@pidlist varchar(30000)

AS

declare @sql nvarchar(30000)

set @sql = '



SELECT

[aid],

[uid],

[tid],

[pid],

[postdatetime],

[readperm],

[filename],

[description],

[filetype],

[filesize],

[attachment],

[downloads],

[attachprice],

[width],

[height]

FROM [dnt_attachments]

WHERE pid in (' + @pidlist + ')'

exec(@sql)

  4)改完从前大伙儿 来跟踪下优化后的性能,看看跟踪效果图(同有一个多 过程,同有一个多 参数,第有一个多 是优化前,第有一个多 是优化后,优化效果灰常满意)

  至此,大伙儿 的优化告一段落。

  原文地址:http://www.cnblogs.com/gezifeiyang/archive/2011/05/02/2034124.html

Tags: discuznt   discuz nt  
责任编辑:mozi