zoukankan      html  css  js  c++  java
  • 优化你的DiscuzNT3.0,让它跑起来(1)看帖篇

    注:本文仅针对 DiscuzNT3.0, sqlserver 2000版本,其他版本请勿对号入座. 

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

     

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

    DiscuzNT给我的印象是

    1)功能很强大,所有你能想到的基本都已经有了;

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

    好了,言归正转,开始我们今天的优化之旅。

    本系统环境如下: 

    软件环境:DiscuzNT3.0 , sqlserver2000,windwos server 2003

    数据环境:主贴表 dnt_topics 约220万条记录,回复表3个,dnt_posts1 约400万, dnt_posts2 约500万, dnt_posts3 约500万,

        附件表 约170万,用户表 dnt_users 约20万, 论坛表 dnt_forums 约5000个论坛

    现象:看帖时,如果帖子包含附件,会很卡;

    目的:优化看帖速度,尤其是有附件的情况 

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

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

     再看下 Posts.GetPostList() 方法的代码:

     1 /// <summary>
     2         /// 获取指定条件的帖子DataSet
     3         /// </summary>
     4         /// <param name="_postpramsinfo">参数列表</param>
     5         /// <returns>指定条件的帖子DataSet</returns>
     6         public static List<ShowtopicPagePostInfo> GetPostList(PostpramsInfo postpramsInfo, out List<ShowtopicPageAttachmentInfo> attachList, bool isModer)
     7         {
     8             List<ShowtopicPagePostInfo> postList = Data.Posts.GetPostList(postpramsInfo);
     9             int adCount = Advertisements.GetInPostAdCount("", postpramsInfo.Fid);
    10 
    11             foreach (ShowtopicPagePostInfo postInfo in postList)
    12             {
    13                 LoadExtraPostInfo(postInfo, adCount);
    14             }
    15             attachList = new List<ShowtopicPageAttachmentInfo>();
    16             if (postList.Count == 0)
    17                 return postList;
    18 
    19             string pidList = GetPidListWithAttach(postList);
    20             attachList = Attachments.GetAttachmentList(postpramsInfo, pidList);
    21             ParsePostListExtraInfo(postpramsInfo, attachList, isModer, postList);
    22             return postList;

    23         } 

    从这里可以看出,DiscuzNT是把所有的帖子id组装成 “ id1,id2,id3,id4 ” 的形式,然后传入数据库,避免多次调用数据库,这个思路很好,现在我们顺藤摸瓜,看看它调用了数据库的脚本,它调用了这个过程 dnt_getattachmentlistbypid, 用profiler跟踪这个过程看看性能。

     

    看上面的图,exec dnt_getattachmentlistbypid @pidlist = '5163797'  这个脚本的cpu=4531,reads=152641,duration=6156,很可观吧,如果同时有10个人来调用这个过程,估计数据库的压力就大了,如果100人,难以想象。那我们怎么来优化这个过程呢,先看看里面它怎么写的,是否用到了索引。

    ALTER   PROCEDURE [dnt_getattachmentlistbypid]
    @pidlist varchar(500)
    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

    GO

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

    1)pid列上是否有索引;

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

    3)优化sql脚本; 

    4)跟踪优化后效果;

    我们一步一个坑往下走:

    1)sp_helpindex dnt_attachments 看看是否有索引,如下图,从图中可以看到pid列上是有索引的,如果没有索引,请建立相关索引

     

    2)看看是否用到了索引,CTRL + L 看看下面语句的执行计划,他用到的索引是 PK_dnt_attachments,根本没用到我们期望的pid

     

     

     3)没用到我们期望的索引,那我们就来优化一下;上面的dnt_getattachmentlistbypid过程里面 WHERE CHARINDEX(','+RTRIM([dnt_attachments].[pid])+',', ','+@pidlist+',')>0 对pid进行了列运算,这个是罪魁祸首,我们想办法把这个列运算去掉,这个过程最终改成下面这个样子:

    ALTER    PROCEDURE [dnt_getattachmentlistbypid]
    @pidlist varchar(500)
    AS

    declare @sql nvarchar(2000)

    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)

    GO

    4)改完之后我们来跟踪下优化后的性能,看看跟踪效果图(同一个过程,同一个参数,第2个是优化前,第4个是优化后,优化效果灰常满意)

     

    至此,我们的优化告一段落。

  • 相关阅读:
    FastWeb2011互联网工具发布
    本站启用新型试用模式
    TDiode单相及三相整流电路辅助设计器发布
    DCOp直流多级电路计算机辅助设计软件下载
    OpDesign2阻容耦合放大电路辅助设计软件下载
    共享软件的思考
    IpAdr网络地址计算器2011发布
    使用JavaScript动态添加复选框Checkbox
    JQuery操作checkbox、radio
    如果Oracle中的字段和数据库的系统字段重名,怎么配置NHibernate的映射实体文件
  • 原文地址:https://www.cnblogs.com/gezifeiyang/p/2034124.html
Copyright © 2011-2022 走看看