日期:2014-05-18  浏览次数:20499 次

海量数据库相关处理问题
1、因为之前没做过大数据处理项目,陆续在这里请教过不少类似的问题,很多大侠热心的帮助了我。
为了方便这里的大侠们了解,我尽量仔细的说明:
之前的三个帖子,比较新一点,回复过的大侠可以很快的了解我的问题所在:
http://topic.csdn.net/u/20090907/10/627bfeec-8bda-4d99-aded-e13435e7c4fe.html
http://topic.csdn.net/u/20090907/16/80f35fbd-3c6c-4ca0-80f7-d55806bf0ddf.html
http://topic.csdn.net/u/20090901/09/b3cd8e71-19be-4694-b43b-0e57cdf4bef2.html

2、针对举例的第二个贴子,为了方便描述,我在这里根据大侠的提议,提出我这边数据搜索的整个问题,分数100;如果系统允许的话,我可以加分数,这个系列问题困扰了我很久;本来我还在尝试用前面几楼提议的去优化,但是感觉真的怎么优化都不咋样····现在50多W的数据,搜索的时候已经很慢了,特别是关键字没有匹配的时候,会全表遍历2边,很慢。(一遍是获取相关总记录数:用于分页(用的是开源的AspNetPager),一遍是获取相关的记录)

3、简单介绍一下这个数据库和硬件,主要用来查询一些信息,目前50W左右数据,以后的话,至少是几百w的数据,甚至是上kw(这个目前先不考虑);存放的是独立托管的一台至强系列服务器,4核,4G内存。数据库和程序放开存放不同的盘符(也可以做到分开存放到2台服务器--如果效率会快的话);系统如果说要跟什么像,有点类似搜索引擎。

4、数据库表:相关的几张表简单描述: InfoTmp、InfoReal、KeyTmp、KeyReal、MyCounry、MyCategory、MyTopic
【InfoTmp】:用于存放临时数据,这些数据都是人工添加的,只有通过审核才会加入InfoReal表;
【InfoReal】:正式数据,用于前台显示;
【KeyTmp】:第3点说到有点类似搜索引擎,就是在这里,用户每搜索一次的关键字,会加入到这个KeyTmp,然后通过计划任务,每天24点,整理后(相同的关键字合并,统计数量;如果正式key表存在则加数量,不存在则新加记录)加入KeyReal;
【MyCounry、MyCategory、MyTopic】:分别存放的是国家,类别,主题信息。
表结构简单举例:
【InfoReal】
[CI_ID],[CI_CorpName],[Country_Continent],[Country_ID],[C_FatherID],[C_ChildID],[CI_MobilePhone],[CI_StateFlag],[CI_CreateTime],[CI_ModifyTime],[CI_ClickTimes],[CI_BuyTimes],[CI_Keywords],[CI_SearchKey]
,[topic_ID],[CI_Charge].......

主要问题所在的存放内容举例: 
----------------------------- 
CI_ID C_FatherID C_ChildID 
10024 1024,1025,1056, 1045,1088,1045,1054,1063, 
10025 1024,1025,1056, 1045,1088,1045,1054,1063, 

----------------------------- 
-----------------------------
【MyCategory】存放内容举例: C_FatherID:0表示为大类
C_ID C_FatherID 
1024 0  
1045 1024 
1054 1025 
-----------------------------
-----------------------------
【MyCounry】存放内容举例: Country_Continent:表示洲,1亚洲,2欧洲....
Country_ID Country_Continent
1024 1  
1045 2
1054 3
-----------------------------
-----------------------------
问题描述:最初的主表设计,信息对于类别(国家,类别,主题是唯一对应的),后来项目已经做好了,领导要求修改:一条信息可以属于多个小类别(也可以属于不同的大类)。于是我把InfoReal的[C_FatherID],[C_ChildID]都改为了字符型,存放的内容见上面内容举例。
再则,最初是没有C_FatherID和Country_Continent;最初数据搜索,都是选择一个大类,然后选择相关小类;国家也一样,先选择洲,然后选择具体国家;后来需求改变,改成了,可以选择1个洲或者多个国家(可以属于不同洲);1个大类或者多个小类(可以属于不同大类);同时还有主题,价格,排序等一些附加搜索条件...于是我陆续在这里请教了一些问题。最初因为项目结构都搞好了,我实在不想改动,后来结合大家的意见和搜索速度实在慢,感觉非常有必要改动。于是我开了这个帖子。

下面我贴出取数据列表的存储过程并做简单说明:
SQL code
ALTER PROCEDURE [dbo].[corpListRealUser]
    -- Add the parameters for the stored procedure here
    @myContinent varchar(10),    --传入洲的值
    @myCountrys varchar(50), --传入国家的值;已处理成sql条件语句,后面说明
    @myCategoryB varchar(10), --传入大类的值
    @myCategorys varchar(50), --传入小类的值;已处理成sql条件语句,后面说明
    @myTopic decimal,  --传入主题的ID
    @myPriceL int,  --传入价格范围的起始
         @myPriceH int,  --传入价格范围的终点
    @myOrderType int,  --传入排序类型(按时间,价格,点击量,购买量)
         @myOrderFlag int,  --传入排序标志(升序还是降序)
    @mySerKeyword varchar(500),  --传入关键字
    @CI_StartRecordIndex int,  --传入分页起始点
    @CI_EndRecordIndex int   --传入分页终结点
AS

BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    -- Insert statements for procedure here
    declare @str varchar(max),@strOrder varchar(200)
    set @str=''    
    if @myTopic>0
        begin
        set @str=@str+'and topic_ID='+rtrim(@myTopic)
        end
    if @myPriceH<500
        begin
        set @str=@str+' and CI_Charge BETWEEN '+rtrim(@myPriceL)