网页教程的分类: .Net编程  Asp编程  Mssql数据库  Mysql数据库  Access数据库  Xml编程  DreamWeaver教程  FireWorks教程  Flash动画教程
网页教程的分类: FrontPage教程  HTML基础教程  PhotoShop教程  动态网站制作  网页设计心得
你现在的位置:首页 >> 网页教程 >> Mssql数据库 >> 正文
文章标题:  sqlserver大数据量统计系统的经验总结
浏览: 来源:网络 作者:admin 发表时间:2008-6-7

项目介绍
政府一个业务系统,
使用范围全国
数据是区域还存储,最大地方,主业务表,一年有600万,工作流表,1年有几千万,迄今为至系统已经运行三年。
其它全国还有46个地点,数据也比较多
新开发系统主要功能,对业务系统的数据进行分析统计.

[E站][网络]


所以对性能要求比较高。

www*eZhannet*com

我们的简要方案。

建立中间表,通过dts调度每天共步数据。
中间表设计原则
 记录数同原表一样,减少多表连接,保存运算好的值,如果记录修改,根据修改日志,重新计算中间值


增量同步数据(dts)
 直接从每天的数据库更改日志读取记录,更新中间表,根据服务器空间程度合理调度dts,减少数据同步时间。

对中间数据进行运算
 查询不作字段运行,所以运算在生成中间表的过程中已经计算

根据查询,优化索引设计
 根据数据查询特性,对where ,group by等操作字段进行索引设计,提高查询速度 

 优化数据类型
 大量采用int提高查询、统计速度 

 优化中间表关键字
 采用int,提高插入速度

数据文件优化设计,一个主要业务,一个数据文件,建数据文件时,估计数据量,一次建一个比较大的文件,这样所分配的文件就是一个连续文件块,

sql server设置区别大小写。初始内存调到一个比较大的内存。 E站*网络

使用我们的toolkit开发简单分页,相关压力测试,
 测试服务器配制
 2个至强3.0cpu
 2g内存
 150g硬盘
 window 2000 advance server中文版+sp4
 测试数据entry_workflow表,数据量2,473,437

www.eZhannet.com


 页数  界面显示时间  cpu  reads i/o  writes i/o  duration
 第1页  2-3 s  642  10689  0 390
 第100页  3-4s  626  128001  0 423
  
 ....后页业数太多,没有必要 E站*网络


 压力测试 www*eZhannet*com

 并发数 平均每秒请求数 未字节响应毫秒数
 50 45.28 20,095.65
 25 45.41 10,043.12 E站*网络

索引优化测试, 

 对分量值小的数据建索引测试,测试语句,group by 分量值
  一个字段,大概有6个分量值,没有建索引,4s,建索引<1s
 两个分量,不建索引,3s,建索引,<1s
一般来说,对分量小的字段,不建索引,但是我们对性能要求太高,根据我们的测试,数据对分量范围小的也要建索引。 E^站^网^络

因为一个统计,有一个很多组合的where,比如有十个指标这样会有十次访问原表,这样性能太低,所以我们把where后的数据作


用中间数据,
十个指标对中间数据作查询,中间数据,我们使用临时表,
经测试,10万条记录,插入操作,临时表需要,16s,表变量需要,40s

select ... into #temp from .......
速度极快,2,500,000条记录,16s 

一个存储过程样例,有兴趣可以分析一下!
eZhannet@com

  1set quoted_identifier on 
  2go
  3set ansi_nulls on 
  4go
  5
  6
  7
  8
  9
 10alter     procedure sp_tg009
 11    /* param list */
 12    @te_i_e_flag varchar(4),/*进出口方式*/
 13    @te_pass_range varchar(4),/*关区范围*/
 14    @te_c_output varchar(4),/*输出方式退单理由输出、申报单位输出、全部输出*/
 15    @te_end_date datetime,/**********申报起止日期********/
 16    @te_end_dateend datetime,/*************************/
 17    @te_moni_t varchar(4),/*监控类型*/
 18    @user_id varchar(64),
 19    @customer_code varchar(4),
 20    @page_number int,
 21    @total_count int output
 22as
 23
 24/******************************************************************************
 25**        file: 
 26**        name: sp_tg009
 27**        desc: 通关业务监控-通关规范监控-报关单退(拒)单管理
 28**
 29**        this template can be customized:
 30**              
 31**        return values:
 32** 
 33**        called by: 
 34**              
 35**        parameters:
 36**        input                            output
 37**     ----------                            -----------
 38**        
 39**        auth: chengdj
 40**        date: 2005-4-7
 41*******************************************************************************
 42**        change history
 43*******************************************************************************
 44**        date:        author:                description:
 45**        --------    --------        -------------------------------------------
 46**    2005-04-11    chengdj                add hgdiv function
 47**      2005-04-11    chengdj                
 48*******************************************************************************/

 49set nocount on
 50
 51declare @sqlwhere varchar(4000)
 52set @sqlwhere = ''
 53
 54set @te_end_dateend = dateadd(day,1,@te_end_dateend)    --结束日期加一天    
 55set @sqlwhere = @sqlwhere + ' te_end_date  >= '''+ convert(varchar(20),@te_end_date+''' and te_end_date < '''+convert(varchar(20),@te_end_dateend)+''''
 56
 57if @te_i_e_flag <> '-2'        ----进出口
 58    set @sqlwhere = @sqlwhere + ' and te_i_e_flag = '''+@te_i_e_flag+''''
 59
 60if @te_pass_range <> '-2'        --关区范围
 61        set @sqlwhere = @sqlwhere + ' and te_pass_range  in ( select a.gcl_code
 62from gl_customer_list a cross join
 63      gl_customer_list b
 64where (a.gcl_layer like b.gcl_layer + ''%'') and (b.gcl_code = '''+@te_pass_range+''')) '
 65
 66/* if @te_c_output<> '-2'        --输出方式
 67    set @sqlwhere = @sqlwhere + 'and '
 68****************监控类型**********************/

 69
 70    /*if @te_moni_t <> '-2'    --监控类型
 71        if @te_moni_t = '2'
 72                 set @sqlwhere = @sqlwhere + ' and  te_scene_flag = 1 '
 73        else
 74                set @sqlwhere = @sqlwhere + ' and  te_worker_flag  =  ' +@te_moni_t + ' '*/

 75/*
 76create table #tg009(            
 77        te_pass_range varchar(4) primary key not null,
 78        man_cle_count int null,            --人工退单报关单总数
 79        man_cle_total int null,            --人工退单报关单总数
 80        man_cle_pct float null,            --人工退单率
 81        elc_cle_count int null,            --电子退单总数
 82        elc_cle_total int null,            --电子退单总次数
 83        man_mu_count int null,            --多次人工退单报关单数
 84        elc_cle_pct float null,            --电子退单率--
 85        re_count int null,                --现场拒单报关单总数--
 86        re_total int null,                --现场拒单报关单总次数--
 87        re_pct float null,                --现场拒单报关单率--
 88        mu_elc_cel_exp float null,        --多次电子退单指数
 89        mu_man_exp float null,            --多次人工退单指数
 90        mu_sec_exp float null            --多次现场拒单指数
 91)
 92    */

 93    declare @sql varchar(8000)
 94    declare @groupby varchar(50)
 95    
 96    if @te_c_output  = '1'    --按申报单位
 97         set @groupby = 'te_agent_code'
 98    else                        --其它按关区
 99         set @groupby = 'te_pass_range'
100         
101         declare @sql2 nvarchar(500)
102           set @sql2 = 'select @count = count(distinct('+@groupby+')) from tg_entry where '+@sqlwhere
103    execute sp_executesql 
104          @sql2,
105          n'@count int output',
106          @total_count output
107          
108declare @start_id int
109declare @end_id int
110set @start_id = (@page_number - 1* 15 + 1
111set @end_id = @page_number * 15
112     
113     ----
114     ----
115     -----     
116     if @te_moni_t = '1'    --人工退单
117                            set @sql = '
118                    select top '+convert(varchar(20),@end_id)+ ' '+ @groupby +',identity(int,1,1) as tid into #page  from tg_entry where '+@sqlwhere +' group by '+@groupby+ ';
119                    create table #tg009(            
120                        '+ @groupby+' varchar(10) primary key not null,
121                        man_cle_count int null,    
122                        man_cle_total int null,
123                        man_cle_pct numeric(10,2) null,
124                        mu_man_exp numeric(10,2) null,
125                        man_cle_total1 int null,
126                        man_cle_total2 int null,
127                        man_cle_total3 int null
128                        );
129
130                    select '+ @groupby+',te_cancel_flag,te_worker_flag,te_end_flag,te_cancel_time into #temp1 from tg_entry where'+@sqlwhere+' and '+@groupby+' in ( select  '+ @groupby +' from #page where tid between '+ convert(varchar(20),@start_id)+ ' and '+ convert(varchar(20),@end_id)+');
131                    insert into #tg009(
132                            '+ @groupby+',
133                            man_cle_count,
134                            man_cle_total,
135                            man_cle_pct,
136                            mu_man_exp,
137                            man_cle_total1,
138                            man_cle_total2,
139                            man_cle_total3) 
140                    select a.'+ @groupby+',
141                    (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 1 and '+ @groupby+' =a.'+ @groupby+'),
142                    (select sum(te_cancel_time) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 1 and '+ @groupby+' =a.'+ @groupby+'),
143                    risk.hgdiv((select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 1 and '+ @groupby+' =a.'+ @groupby+'),(select count(*) from #temp1 where te_end_flag = 1 and te_worker_flag = 1 and '+ @groupby+' =a.'+ @groupby+')),
144                    risk.hgdiv((select sum(te_cancel_time) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0  and '+ @groupby+' =a.'+ @groupby+'),(select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0  and '+ @groupby+' =a.'+ @groupby+')),
145                    (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 1 and te_cancel_time = 1 and '+ @groupby+' =a.'+ @groupby+'),
146                    (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 1 and te_cancel_time = 2 and '+ @groupby+' =a.'+ @groupby+'),
147                    (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 1 and te_cancel_time > 2 and '+ @groupby+' =a.'+ @groupby+')
148                    from #temp1 a
149                    group by a.'+ @groupby+';
150                    drop table #temp1;
151                    select * from #tg009;
152                    drop table #tg009'
153    else if        @te_moni_t = '0'    --电子
154                set @sql = '
155                select top '+convert(varchar(20),@end_id)+ ' '+ @groupby +',identity(int,1,1) as tid into #page  from tg_entry where '+@sqlwhere +' group by '+@groupby+ ';
156                create table #tg009(            
157                    '+ @groupby+' varchar(10) primary key not null,
158                    elc_cle_count int null,
159                    elc_cle_total int null,
160                    elc_cle_pct numeric(10,2)  null,
161                    mu_elc_cel_exp numeric(10,2) null,
162                    elc_cle_count1 int null,
163                    elc_cle_count2 int null,
164                    elc_cle_count2b int null
165                );
166                select '+ @groupby+',te_cancel_flag,te_worker_flag,te_end_flag,te_cancel_time into #temp1 from tg_entry where'+@sqlwhere+' and '+@groupby+' in ( select  '+ @groupby +' from #page where tid between '+ convert(varchar(20),@start_id)+ ' and '+ convert(varchar(20),@end_id)+');
167                insert into #tg009(
168                        '+ @groupby+',
169                        elc_cle_count,
170                        elc_cle_total,
171                        elc_cle_pct,
172                        mu_elc_cel_exp,
173                        elc_cle_count1,
174                        elc_cle_count2,
175                        elc_cle_count2b) 
176                select a.'+ @groupby+',
177                (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0 and '+ @groupby+' =a.'+ @groupby+'),
178                                (select sum(te_cancel_time) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0 and '+ @groupby+' =a.'+ @groupby+'),
179                                risk.hgdiv((select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0 and '+ @groupby+' =a.'+ @groupby+'),(select count(*) from #temp1 where te_end_flag = 1 and te_worker_flag = 0 and '+ @groupby+' =a.'+ @groupby+')),
180                                risk.hgdiv((select sum(te_cancel_time) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0  and '+ @groupby+' =a.'+ @groupby+'),(select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0  and '+ @groupby+' =a.'+ @groupby+')),
181                                (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0 and te_cancel_time = 1 and '+ @groupby+' =a.'+ @groupby+'),
182                                (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0 and te_cancel_time = 2 and '+ @groupby+' =a.'+ @groupby+'),
183                                (select count(*) from #temp1 where te_cancel_flag = 1 and te_worker_flag = 0 and te_cancel_time > 2 and '+ @groupby+' =a.'+ @groupby+')
184                from #temp1 a
185                group by a.'+ @groupby+';
186                drop table #temp1;
187                select * from #tg009;
188                drop table #tg009'
189        
190    else if        @te_moni_t = '2'    --现场拒单
191            set @sql = '
192            select top '+convert(varchar(20),@end_id)+ ' '+ @groupby +',identity(int,1,1) as tid into #page  from tg_entry where '+@sqlwhere +' group by '+@groupby+ ';
193            create table #tg009(            
194                '+ @groupby+' varchar(10) primary key not null,
195                re_count int null,
196                re_total int null,
197                re_pct numeric(10,2) null,
198                mu_sec_exp numeric(10,2) null,
199                re_total1  int null,
200                re_total2  int null,
201                re_total2b  int null
202            );
203            select '+ @groupby+',te_scene_time,te_cancel_flag,te_scene_flag,te_meet_flag into #temp1 from tg_entry where'+@sqlwhere+' and '+@groupby+' in ( select  '+ @groupby +' from #page where tid between '+ convert(varchar(20),@start_id)+ ' and '+ convert(varchar(20),@end_id)+');
204            insert into #tg009(
205                    '+ @groupby+',
206                    re_count,
207                    re_total,
208                    re_pct,
209                    mu_sec_exp,
210                    re_total1,
211                    re_total2,
212                    re_total2b) 
213            select a.'+ @groupby+',
214            (select count(*) from #temp1 where te_scene_flag = 1 and '+ @groupby+' =a.'+ @groupby+'),
215            (select sum(te_scene_time) from #temp1 where te_scene_flag = 1 and '+ @groupby+' =a.'+ @groupby+'),
216          &