优化你的DiscuzNT,让它跑起来

去年用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,代码如下:

  1. 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人,难以想象。那我们怎么来优化这个过程呢,先看看里面它怎么写的,是否用到了索引。

  1. ALTER   PROCEDURE [dnt_getattachmentlistbypid]  
  2. @pidlist varchar(500)  
  3. AS 
  4. SELECT   
  5. [aid],  
  6. [uid],  
  7. [tid],  
  8. [pid],  
  9. [postdatetime],  
  10. [readperm],  
  11. [filename],  
  12. [description],  
  13. [filetype],  
  14. [filesize],  
  15. [attachment],  
  16. [downloads],  
  17. [attachprice],  
  18. [width],  
  19. [height]   
  20. FROM [dnt_attachments]   
  21. WHERE CHARINDEX(','+RTRIM([dnt_attachments].[pid])+','','+@pidlist+',')>0GO 

这里主要查找的条件是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进行了列运算,这个是罪魁祸首,我们想办法把这个列运算去掉,这个过程最终改成下面这个样子:

  1. ALTER    PROCEDURE [dnt_getattachmentlistbypid]  
  2. @pidlist varchar(500)  
  3. AS 
  4.  
  5. declare @sql nvarchar(2000)  
  6.  
  7. set @sql = '  
  8. SELECT   
  9. [aid],  
  10. [uid],  
  11. [tid],  
  12. [pid],  
  13. [postdatetime],  
  14. [readperm],  
  15. [filename],  
  16. [description],  
  17. [filetype],  
  18. [filesize],  
  19. [attachment],  
  20. [downloads],  
  21. [attachprice],  
  22. [width],  
  23. [height]   
  24. FROM [dnt_attachments]   
  25. WHERE pid in (' + @pidlist + ')'  
  26.  
  27. exec(@sql)  
  28. GO 

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

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

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

【编辑推荐】

  1. 浅述当前模式读与一致性读续
  2. 浅述当前模式读与一致性读的区别
  3. 告诉你,如何成就DBA职业生涯
  4. DBA应用技巧:如何升级InnoDB Plugin
  5. MySQL日志操作教程:DBA们管理的利器

 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/229018.html<

(0)
管理的头像管理
上一篇2025-04-18 14:01
下一篇 2025-04-18 14:02

相关推荐

  • 骨干网络体系结构能干什么?骨干网络体系结构的作用

    骨干网络体系结构是现代信息社会的“超级高速公路网”,它通过分层设计、冗余备份和智能调度,确保海量数据在全球范围内高速、稳定、安全地传输,是支撑云计算、物联网及人工智能应用的底层基石,想象一下,如果你把互联网比作一个巨大的城市交通系统,那么骨干网络就是连接各个城市的主干道和立交桥,没有它,你的每一次微信发送、每一……

    2026-06-18
    0
  • 高io数据库可以干什么用?高io数据库适合什么场景

    高IO数据库的核心价值在于通过极高的读写吞吐量,解决海量数据场景下的性能瓶颈,是支撑高并发交易、实时分析及大规模内容分发的关键基础设施,在数字化转型的深水区,数据不再仅仅是静态的记录,而是流动的资产,传统的机械硬盘或普通SSD早已无法满足现代应用对速度的极致追求,高IO(Input/Output)数据库,就是那……

    2026-06-18
    0
  • 高io服务器性能如何?高io服务器适合什么场景

    高IO服务器并非单纯指代某种硬件,而是指在随机读写、高并发连接及小文件处理场景下,具备极致IOPS(每秒输入输出操作次数)和低延迟特性的计算资源,它是支撑现代高并发应用稳定运行的核心基石,在2026年的数字化浪潮中,业务负载早已从简单的静态页面展示演变为复杂的实时数据处理,许多开发者在排查系统瓶颈时,往往忽略了……

    2026-06-18
    0
  • 隔离网络空间哪里便宜?国内隔离网络空间价格

    隔离网络空间并没有统一的“便宜”标准,其成本高度取决于物理隔离等级、带宽需求及安全合规要求,通常物理网闸方案初期投入较高但长期运维成本低,而逻辑隔离方案虽初期便宜但存在潜在安全风险,建议根据业务敏感度选择混合隔离架构以平衡成本与安全,在数字化时代,企业构建独立网络环境的需求日益增长,但“隔离网络空间哪里便宜”这……

    2026-06-18
    0
  • 骨干网络体系结构设备为何故障?常见原因有哪些

    骨干网络体系结构设备故障的核心原因通常归结为硬件老化、配置错误、物理链路中断及外部攻击四大类,其中电源模块失效与光模块性能衰减是占比最高的隐性故障源,骨干网作为数字经济的“大动脉”,其稳定性直接关乎国计民生,当核心路由器或交换机出现丢包、震荡甚至宕机时,运维人员往往面临巨大的压力,很多人第一反应是检查软件配置……

    2026-06-18
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注