[已解决问题] 求论坛分区方案
提问时间: 2008-05-20 17:16
悬赏分:20 浏览:374 次

论坛最常用的功能有两个,一是版面首页显示版面的帖子列表;二是显示帖子和帖子回复
现在我建了帖子表
----------------------------
USE [DB_Forum]
GO
CREATE TABLE [dbo].[Forum_Post_tab](
 [ID] [bigint] NOT NULL,
 [BoardID] [int] NOT NULL,
 [Title] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
 [Content] [nvarchar](max) COLLATE Chinese_PRC_CI_AS NOT NULL,
 [ReplyCount] [int] NOT NULL,
 [PageView] [int] NOT NULL,
 [StatusFlags] [int] NOT NULL,
 [CreateUserID] [bigint] NOT NULL,
 [CreateUserName] [varchar](40) COLLATE Chinese_PRC_CI_AS NOT NULL,
 [CreateTime] [datetime] NOT NULL,
 [CreateIP] [varchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
 [UpdateIP] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL,
 [LatestReplyTime] [datetime] NOT NULL,
 [LatestReplyUserID] [bigint] NULL,
 [LatestReplyUserName] [nvarchar](18) COLLATE Chinese_PRC_CI_AS NULL,
 [ResourceCode] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 [PollIDs] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL)
GO
--------------------
想对该表进行表分区,我计划的分区方案是根据版面来进行分区,例如版面id为1-100的在一个分区上,101-200的在一个分区上;这样分区就需要把BoardID放在聚集索引中,于是我在两列ID和BoardID上建了聚集索引。

这样分区的原因有二,一可以提高帖子列表页的帖子列表的查询速度;二是在显示帖子详细页时我总是会传BoardID和PostID这样在查询的条件中我可以先写BoardID = @boardID AND ID = @postID希望这样可以提高帖子详细页数据查询的效率

 

请各位指点,我这样做是否合适?有什么问题,有没有合适的方案?

 

先谢过大家。

提问者:玉开 - 大侠五级
最佳答案
这个问题需要从逻辑和物理两方面来看。 逻辑方面: 1. 同上面各位兄弟说的,数据量不大就别分区了(这对物理方面的影响是很大的)。 2. 你的版面有那么多吗?如果要在某一个版面中列出所有帖子标题的话,为什么不直接按版面分区?或者可以将量大的单独放一个分区,量少的放在一起(方法很简单,从版面ID入手,也就是说好好对你的版面进行ID设计)。如果仅仅是为了分区而分区,那还不如不要分区。 3. 你的论坛不用全站查询?如果要列出全站的帖子列表呢?这样的情况多不多?聚集索引会随了表分区的哦,这个对性能不是没有影响的哦。如果你用的是SQLServer2005的话,这样的查询实现起来虽然不会像SQLServer2000那么费事,但是除了执行计划好了那么一些些之外,别的几乎没区别的。 物理方面:(总的一句话,数据库就是一堆放在硬盘上的东西,性能在很大程度上其实就是读写速度) 1. 你的这些分区有没有硬件支持(就是说硬盘,还有就是CPU了,不过CPU的作用稍微小点,要看你的查询用不用得上了,此外,还有一些其他的硬件支持,这里不多说了)?没有的话,实际上也起不了多么多么显著的作用,至少也要多弄几个文件组吧?(但这又影响了全站帖子列表的性能。) 2. 你的分区列为版面ID,且聚合也在这里,这个倒是不错,可以避免不必要的空间浪费,这也无形中为性能提升带来了机会。 这个问题说起来真是太费口舌了,这样说吧,建议你按各版面的帖子量进行分区,好好设计一下版面ID即可。如果是SQLServer2005,要加减分区也是一件非常简单的事情,而且不会浪费什么资源(几乎仅仅就是配置,不会涉及到数据迁移的,所以这个操作是很快的)。 另外,再多说几句: 1. 你的聚集索引一定要弄好顺序,不然就郁闷了。(兴许这是废话) 2. “一可以提高帖子列表页的帖子列表的查询速度”,的确,不过仅仅是同版面内的,跨版面的就不好说了,搞不好会比没分区时更慢(情况太多,兄弟就自己慢慢测试吧)。 3. “二是在显示帖子详细页时我总是会传BoardID和PostID这样在查询的条件中我可以先写BoardID = @boardID AND ID = @postID希望这样可以提高帖子详细页数据查询的效率”。首先,不要低估了查询优化器的本事。第二,如果只是要找某一个帖子的内容,这里高出来的性能几乎可以忽略不计。第三,你这个条件就已经定死了某条post了,其他的查询条件将直接54。 说了这么多,不知道lz是否看糊涂了,没办法,我对数据库也只是一知半解,权当是抛砖引玉了……囧rz 反正我对数据库优化的理解就是:要全盘考虑,否则不要贸然乱搞,否则可能会犯“捡了芝麻丢了西瓜”的原则性错误^_^
2008/5/23 1:12:24 回答者:电机拖动


提问者对于答案的评价:多谢, 对在两列上建聚集索引的索引顺序应该注意什么,还望详解。
其它回答(4)
好象有点过度优化~~~你贴子量有多少了啊~~用得着吗~~
3个月前   回答者:沙加 - 老鸟四级
1 您说到:" 这样分区就需要把BoardID放在聚集索引中,于是我在两列ID和BoardID上建了聚集索引" -- 一个表上 可以建立两个聚集索引么? 2 该表是帖子表,大概在一般的论坛中(例如Discuz!NT)相当于dnt_topics吧, 不知道存储回复的表什么结构呢? 3 您所说的分区应该是对表进行横向分区吧,这样需要一个表来记录分表的具体范围情况 Forum_PostTableList_tab 例如 ID PostTableName BoardMinID BoardMaxID 1 Forum_Post1_tab 1 100 2 Forum_Post2_tab 101 200 一般情况下一个论坛的版块不会太多,有200已经算是极品了,这样在您的帖子表中将会有很多BoardID重复的记录,貌似这样的记录还算适合建立聚集索引吧 但是 我想 您需要在从帖子列表页(主题列表页)转向帖子详细页时 带一个BoardID过来才行。 您些 BoardID = @boardID AND ID = @postID 其中的 【ID】 应该是 回复表中的ID吧。 而@PostID是 帖子表中的ID吧。。。 小弟悟性实在不好,可能理解错误了 ……
3个月前   回答者:戏水 - 菜鸟二级
我也感觉有点过度优化了 一个论坛实际活跃的BoardID能有几个呢 不多吧 这比例建聚集似乎不很合适,而且这个表按说应该是比较常进行插入的
3个月前   回答者:wsky - 菜鸟二级
看你数据什么量级的,同楼上,帖子量不大根本不需要这么设计,回复表分区的意义更大
3个月前   回答者:tangle - 菜鸟二级
评论
3个月前   玉开 :
谢谢各位的答复,假定我有足够大的数据量,没有过度优化,该如何分区,谢谢。

另外回复表的结构和帖子表差不多,也存在分区的问题,大家指点一下。不要假定过度优化,谢谢。

还有就是id的1-100;2-100的比例是假定的,我可以在1-100之间只有1个或者10个版面id;id可以是不连续的,设计成100一组是为了增加灵活性。
3个月前   玉开 :
多谢,你的答复,全站查询我们不会用sql server提供的查询,而是有专门的检索服务器负责。

另外,请问“你的聚集索引一定要弄好顺序”这个顺序应该注意些什么呢?


3个月前   电机拖动 :
另外,请问“你的聚集索引一定要弄好顺序”这个顺序应该注意些什么呢?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
很简单,就两点:
1. 索引覆盖,这个就不用我废话了
2. 如果打算按照版面ID分区,而版面ID在聚集索引中没有处于首位,想想数据到底会存成什么样吧。这实际上也是为了能够利用硬盘的预读功能(早在白垩纪,我们就成天说“某某硬盘的缓存有2M了,真牛啊!”,就是这么个道理)。
3个月前   玉开 :
关于聚集索引包含两个列时的索引结构,还不是太明白,可否再说详细一点,谢谢。

   您需要登录以后才能回答!
 

我要提问

我的问题


快到期问题

> 问题排行榜

相关链接