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个是优化后,优化效果灰常满意)

     

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

  • 相关阅读:
    UVa 1151 Buy or Build【最小生成树】
    UVa 216 Getting in Line【枚举排列】
    UVa 729 The Hamming Distance Problem【枚举排列】
    HDU 5214 Movie【贪心】
    HDU 5223 GCD
    POJ 1144 Network【割顶】
    UVa 11025 The broken pedometer【枚举子集】
    HDU 2515 Yanghee 的算术【找规律】
    Java基本语法
    Java环境变量,jdk和jre的区别,面向对象语言编程
  • 原文地址:https://www.cnblogs.com/gezifeiyang/p/2034124.html
Copyright © 2011-2022 走看看