|
项目介绍 政府一个业务系统, 使用范围全国 数据是区域还存储,最大地方,主业务表,一年有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
1 set quoted_identifier on 2 go 3 set ansi_nulls on 4 go 5 6 7 8 9 10 alter 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 22 as 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 *******************************************************************************/ 49 set nocount on 50 51 declare @sqlwhere varchar(4000) 52 set @sqlwhere = '' 53 54 set @te_end_dateend = dateadd(day,1,@te_end_dateend) --结束日期加一天 55 set @sqlwhere = @sqlwhere + ' te_end_date >= '''+ convert(varchar(20),@te_end_date) +''' and te_end_date < '''+convert(varchar(20),@te_end_dateend)+'''' 56 57 if @te_i_e_flag <> '-2' ----进出口 58 set @sqlwhere = @sqlwhere + ' and te_i_e_flag = '''+@te_i_e_flag+'''' 59 60 if @te_pass_range <> '-2' --关区范围 61 set @sqlwhere = @sqlwhere + ' and te_pass_range in ( select a.gcl_code 62 from gl_customer_list a cross join 63 gl_customer_list b 64 where (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 /**//* 76 create 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 108 declare @start_id int 109 declare @end_id int 110 set @start_id = (@page_number - 1) * 15 + 1 111 set @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 & |