资源描述
DB2性能、安全和规范相关要点
V1.5
------修订的版本历史-------
修订者
修订日期
修订内容
高健、刘红波、李双全
2010-09-13
创建PPT版。
高健
2011-07-27
创建问答。版本V0.8。
高健
2011-07-28
采纳符松建议后,从应用角度进行问答描述。版本V0.9。
高健
2011-7-29
采纳耿珍建议后,增加了目录,便于检索;以及进行了版本管理。版本V1.0。
高健
2011-8-8
根据8月4日,IBM工程师的建议增加了“通过执行计划查看不合理的嵌套连接NLJOIN”及优化步骤。版本V1.1。
高健
2011-8-17
根据8月16,亚联公司发布的《ODS数据库常用字段定义规范》,增加“SERV_ID等常用字段的长度为什么需要统一”。版本V1.2。
高健
2011-9-21
根据9月15日贾文学处理故障的经验,通过减少对字段的函数处理来提升SQL性能;根据8月账期出现的程序不规范,例如,月报表使用日套表等情况,增加相关程序规范,提升数据质量;并将文档的定位进行扩充,在性能、安全的基础上增加了规范。版本V1.3。
高健
2012-2-21
对“关闭数据库事务日志”方面的要求进一步进行了强化,确保避免在数据测试中由于操作失误导致数据库瘫痪。版本V1.4。
刘红波、刘祥、高健、李兰田、符松
2012-3-29
增加3条: “新增、修改套表的流程及注意事项”、“SQL中NOT IN语法的注意事项”、“主产品、账目和套餐归并的统计指标进行集中管理的规范”。版本V1.5。
-------------目录------------
DB2性能、安全和规范相关要点 1
1. SERV_ID等常用字段的长度为什么需要统一?如何查看这些字段的统一定义要求? 3
2. 如何通过“执行计划”查看不合理的嵌套连接NLJOIN,从而优化多表连接(关联)的SQL性能? 4
3. 建表时,为什么必须指定分区键(PARTITIONING KEY)?指定分区键必须注意些什么? 6
4. 如何判断某个表的数据在各节点的空间有木有偏移(即,分区键合不合理)? 6
5. 为什么要求绝大部分数据处理SQL须关闭数据库事务日志?在哪些情况下,才可以不关闭事务日志? 7
6. 在下面的三个场景中执行SQL,怎样才能真正实现事务日志的关闭:1)CRT TELNET后台方式?2)TCL程序中?3)RAPID SQL工具中? 7
7. LOAD过程中如何查看入库的进展?若发现异常、终止,必须立即执行的语句是什么?如何清除表的LOAD状态? 8
8. 若一旦发现正在执行的SQL有异常(例如,笛卡尔积……),需杀之,应该如何处理? 8
9. 怎样看ODS或EDA的数据库空间满否?该信息多久更新一次?其中,TBSP_FREE_PAGES、KEEP、PER这三个字段的含义是什么? 8
10. 建表时,为什么必须指定表空间?其中,“报表、开发、临时性统计(即,除通过版本正式上线外)”人员建表时,必须分别放入三个专用的空间,它们的名字分别是什么? 9
11. DROP或DELETE全表数据前,必须先执行什么语句才能释放空间?为什么部分命令将表的数据删除或压缩后,数据库的空间不释放? 9
12. 为什么用LIKE、AS命令建表时,容易发生节点空间偏移,还把TBS_DIM表空间给涨爆了? 10
13. 系统表syscat.tables的以下常用字段的含义是什么?要看到某个表的这些字段信息,需要先运行什么命令?其中,常用语句和字段:select owner,definer,tabname,CARD ROWS,FPAGES,tbspace,STATS_TIME,CREATE_TIME,COMPRESSION,AVGROWCOMPRESSIONRATIO AVG from syscat.tables where tabname like 'DS%201101‘ 10
14. 为什么要做表的数据重组(压缩)reorg?ODS的哪些情况下需要尽快执行reorg?如何查看表的实际压缩比例? 11
15. 表数据重组(压缩)reorg命令的两种常用格式?为什么在RAPID SQL工具中执行报错? 11
16. 为什么有些表执行reorg命令后,实际压缩比例还是0,是不是需先确保一个属性?如何在建表语句中指定该属性?若建表中未指定,如何调整?如何查看某个表的该属性? 11
17. 为什么要更新表的统计信息runstats?哪些情况下需要对表做runstats? 12
18. runstats命令的两种常用格式?为什么在RAPID SQL工具中执行报错?其中,哪种情况建议采用抽样10%的统计信息更新方式? 12
19. 为什么在连接数据库后,必须在执行SQL后尽快断开数据库链接?其中,RAPID SQL工具和CRT TELENET工具要如何才能真正的断开数据库连接? 12
20. 为什么“调度依赖不完整”和“RAPID SQL工具的数据库连接不断开”会导致EDA程序时常报 “锁等待超时”的生产故障? 13
21. 为什么营维支撑系统的前端表要使用分区表?建表语法是什么?判断是不是分区表的方法?如果发现分区表坏了后,咋个办? 13
22. 为什么ODS大部分情况下,使用表的锁(LOCK)为“表级”?另外,“行级”锁用于那些场合?指定表的锁(LOCK)类型的语句? 14
23. 在ODS中,为什么大部分表不需要建索引?在哪些场合才有必要建索引? 哪些字段不适合建索引? 14
24. 表的APPEND ON 属性是什么意思?如何设置这个属性? 14
25. 综合考虑一个表的常用属性后,一个完整的建表SQL语法示例?例如, 15
26. 建表、删表操作可不可以在程序中动态执行?一般哪个时候执行? 15
27. 数据库的表张数太多,对性能有木有影响?列举哪些措施降低表的张数? 15
28. 如果嫌dbpartitionnum函数运行速度太慢,有木有快速、大致估算某个表的各节点空间偏移情况的语句?为此,如果发现一个空间的2个节点严重偏移(8%以上),如何才能通过快速、批量运算,轻松揪出是哪些表的分区键指定得有问题? 16
29. 在进行文件入库时,如何避免数据重复LOAD而导致表中数据重复? 在进行表出库时,如何避免DECIMAL类型的字段出现"+"、"000"等符号? 17
30. 观察数据库主机当前的运行性能的vmstat命令格式?主要看哪些指标?是什么意思? IDLE是什么意思? 17
31. 为什么减少对字段的函数处理可以大大提升SQL性能?如何改进? 17
32. 在程序开发中,为什么月报的数据来源不能是日套表、DM表等每日会变化的数据? 18
33. 新增、修改套表的流程及注意事项有哪些? 18
34. SQL中NOT IN语法的注意事项? 18
35. 主产品和套餐(含优惠)的归并统计指标进行集中管理规范? 19
---------------正文--------------
1. SERV_ID等常用字段的长度为什么需要统一?如何查看这些字段的统一定义要求?
问题一:对于DB2数据库,在表关联查询时,如相互匹配的两个字段数据类型不一致(包含定义的数据长度不一致,例如,一个字段为decimal(16,0),另一个为decimal(20,0))会引起数据库sql优化器无法使用最优的join方式进行关联查询,会出现大表关联时使用MSJOIN或NLJOIN的情况,严重影响查询效率。
问题二:根据亚信发布的《ODS数据库常用字段定义规范 v1.0》,SERV_ID等常用字段的定义统一存储在tbowner.sys_table_columns_Standard表中,信息包括“字段名,字段中文名,字段类型,字段长度,字段说明”。若大家在生产过程中,希望补充、完善该信息,可以与亚联公司的维护组(目前,刘红波)联系,由亚联公司统一维护。
2. 如何通过“执行计划”查看不合理的嵌套连接NLJOIN,从而优化多表连接(关联)的SQL性能?
对于开发人员,在上线前的试运行时,务必通过查看“执行计划”,诊断多表连接的SQL的性能是否合理;对于运行维护人员,若发现一个多表连接的SQL在20分钟内无法成功,也务必通过查看“执行计划”,查看是否存在不合理的连接方式(嵌套连接NLJOIN),或者大数据量的MSJOIN。最后,根据相应的优化步骤逐一实施,消灭掉不合理的嵌套连接NLJOIN、MSJOIN。
其中,1)查看SQL的执行计划的方法,详见“SQL的执行计划”专题;2)三种表连接方式的含义,详见“表的连接方式”专题;3)关于消灭掉不合理的连接方式的优化方法,详见“如何消灭掉不合理的嵌套连接NLJOIN”专题。
专题一:查看“SQL的执行计划”
查看SQL的执行计划常用方法有两种:一种是通过CRT工具后台执行;一种是通过第三方的DbVisualizer 7.1.1工具 或者TOAD工具,或者高版本的DB2客户端(9.5版以上),另,Rapid SQL 7.6.0暂时无法运行该功能。
方法一:对于ODS,在CRT工具上必须使用tbowner数据库用户登陆,执行命令如下:
[ods_db1] /home/tbowner/gj $ db2expln -g -d cqods -z ';' -f a2011080816.sql -o a2011080816.exp
其中,a2011080816.sql为需要分析的SQL所保存的文件;a2011080816.exp为分析后的执行计划输出文件;
通过[ods_db1] /home/tbowner/gj $ more a2011080815.exp 查看输出文件尾部的“执行计划”树形图。例如图1,
方法二:对于第三方的DbVisualizer 7.1.1工具 或者TOAD工具,或者高版本的DB2客户端(9.5版以上),另,Rapid SQL 7.6.0暂时无法运行该功能。必须使用tbowner用户,执行这些工具中的“Explain Plan”之类的命令即可看到如下图结果。
专题二:“表的连接方式”有哪些?
DB2优化器在执行表的连接时,会在三种连接方式中自动选择一种。三种连接方式分别为:哈希连接(HSJOIN)、合并连接(MSJOIN)、嵌套连接(NLJOIN)。其中,HSJOIN和MSJOIN方式的速度均比较快,但是,由于MSJOIN需排序,所需的资源较HSJOIN大一些,所以,对于大数据量的表MSJOIN,则需要优化;而对于NLJOIN,由于需要嵌套循环,速度非常低,必须彻底消灭掉不合理的嵌套连接NLJOIN。
专题三:“如何消灭掉不合理的嵌套连接NLJOIN” ?
通过以下三步逐一进行核查、优化(MSJOIN的优化方法与NLJOIN一样):
步骤1:作为连接条件的列数据类型定义不一致,例如,serv_id,一个表定义为decimal(12,0),一个表定义为decimal(14,0)
步骤2:作为连接条件的列上有函数运算,例如,a.acc_nbr=substr(b.acc_nbr,5,20)
步骤3:对应表上没有收集统计信息,SQL优化引擎不能做出正确判断。其中,如何查看是否有统计信息,详见syscat.tables问答;如何收集统计信息,详见runstats问答
3. 建表时,为什么必须指定分区键(PARTITIONING KEY)?指定分区键必须注意些什么?
问题一:首先,从分区键(PARTITIONING KEY)的作用看,数据库将根据此键把表的数据存储通过HASH算法分布到8个节点,便于8个节点并行处理,提升性能;若在建表语句中不指定表空间,系统则会默认用表的第一个字段,这样极有可能导致表空间各节点间的偏移、空间浪费,同时,降低处理性能。例子,create table aa (……) PARTITIONING KEY(serv_id) ;
问题二:指定分区键必须注意三大方面:
1)建表时,勿忘指定KEY:因为,若不指定,则将默认为第一个字段,难以满足第二点。
2)指定KEY的字段(或字段组合)的数据值要尽量多、数据分布要尽量均匀;若一个字段满足不了,则需要多找几个字段,用逗号分隔,组合成KEY。
3)大表关联的主要字段最好在KEY中,除非要为这个字段建索引。
4. 如何判断某个表的数据在各节点的空间有木有偏移(即,分区键合不合理)?
select dbpartitionnum(serv_id),count (*) from tabname group by dbpartitionnum(serv_id) order by 1;
其中,(serv_id为该表任意取一个字段)
5. 为什么要求绝大部分数据处理SQL须关闭数据库事务日志?在哪些情况下,才可以不关闭事务日志?
问题一:从数据库事务日志记录的作用看,记录SQL事务操作(增、删、改)的数据日志,便于提供各种异常中断后的回滚等恢复功能;但是,若事务操作所涉及数据量大,则不仅会导致数据处理效率下降,而且容易导致事务日志满而被迫回滚,使整个数据库几乎瘫痪。为此,“除在表被损坏之后一定会导致数据丢失、无法恢复和再现以外,执行SQL必须关日志”
特别说明:由于测试过程中无法完全预测数据量,为此,数据测试、验证处理过程中即使数量特别少,也必须关闭事务日志执行SQL。
问题二:在“表被损坏之后一定会导致数据丢失、无法恢复和再现,且每次事务记录数小于50万以下”情况下,可以不关闭事务日志。如果事务操作对象是汇总表、且记录数量大,则必须拆分为套表模式后,关闭日志处理。
6. 在下面的三个场景中执行SQL,怎样才能真正实现事务日志的关闭:1)CRT TELNET后台方式?2)TCL程序中?3)RAPID SQL工具中?
对于每个场景,在建表时,均需要指定“NOT LOGGED INITIALLY”。例子,create table aa (……) NOT LOGGED INITIALLY ;
场景一:CRT TELNET后台方式关闭日志,需两步完成:
首先,将以下脚本在136.6.6.190 主机上 保存为 xxxx.db2 文件
update command options using c off;
connect to cqods user ??? using ??????;
ALTER TABLE tbowner.aaa ACTIVATE NOT LOGGED INITIALLY;
insert into tbowner.aaa select b.* from tbowner.bbb b;
commit;
terminate;
然后,运行以下命令,执行以上脚本文件:nohup db2 -tvf xxxx.db2 > xxxx.log &
场景二:TCL程序中关闭日志:
通过传递关闭日志参数实现,例如:ds_chn_prd_serv_02_ms.tcl程序中set entity_count1 [f_handle_sql $sqlBuff1 ${ptemp_table_01} "Y"]
场景三:RAPID SQL工具中关闭日志:该工具没得办法实现关闭日志,切忌。
7. LOAD过程中如何查看入库的进展?若发现异常、终止,必须立即执行的语句是什么?如何清除表的LOAD状态?
问题一:在LODD过程中,请及时查看load状态:
db2 connect to dbname user username using passwd
db2 load query table tbowner.FX_COMM_SERV_201101_01
问题二:若通过上面语句看到有异常情况,请立刻终止装载数据,并务必立即执行以下语句:
db2 load CLIENT from /dev/null of del terminate into TBOWNER.FX_COMM_SERV_201101_01
问题三:若LOAD过程中异常终止后,表会因为仍处于LODA状态而无法访问,也是通过运行问题二的语句来清除LODA状态。
8. 若一旦发现正在执行的SQL有异常(例如,笛卡尔积……),需杀之,应该如何处理?
立即拿起你的电话,联系超级系统管理员,只有此角色用户才有权限处理:目前为,管运部 (刘利芬18983395030);或亚联 (李双全 18983818393)
9. 怎样看ODS或EDA的数据库空间满否?该信息多久更新一次?其中,TBSP_FREE_PAGES、KEEP、PER这三个字段的含义是什么?
问题一:查看ODS或EDA的当前表空间使用情况:
select value(substr(TBSP_NAME,1,12),'ALL') TBSPNAME,value(substr(char(DBPARTITIONNUM),1,6),'ALL') DBNUM,
sum(TBSP_CURRENT_SIZE)/1024/1024/1024 "TBSP_CURRENT_SIZE(GB)",
sum(TBSP_TOTAL_PAGES) TBSP_TOTAL_PAGES,
sum(TBSP_USABLE_PAGES) TBSP_USABLE_PAGES,
sum(TBSP_USED_PAGES) TBSP_USED_PAGES,
sum(TBSP_FREE_PAGES) TBSP_FREE_PAGES,
decimal(decimal((sum(TBSP_USABLE_PAGES)-sum(TBSP_USED_PAGES)-sum(TBSP_FREE_PAGES)),12,2)/sum(TBSP_USABLE_PAGES)*100,4,2) keep,
decimal((decimal(sum(TBSP_USED_PAGES))/decimal(sum(TBSP_USABLE_PAGES))),4,2)*100 PER
from db2inst1.check_ods_tbs_moni
where TBSP_NAME not in ('SYSCATSPACE','TEMPSPACE1','STMP32K','STMP32K_02','SYSTOOLSPACE','STMP32K_03','SYSTOOLSTMPSPACE','TBS_DEFAULT','TBS_TEMP')
and INSERT_TIME = (select max(INSERT_TIME) from db2inst1.check_ods_tbs_moni)
group by grouping sets((substr(TBSP_NAME,1,12),DBPARTITIONNUM),substr(TBSP_NAME,1,12),())
order by value(substr(TBSP_NAME,1,12),'ALL'),value(char(DBPARTITIONNUM),'ALL');
问题二:该表的数据更新频率为:5分钟,但凌晨0:00~7:00期间,由于出账不更新。
问题三:TBSP_FREE_PAGES、KEEP、PER分别表示:剩余页面数、未释放的空间%、空间使用率%
10. 建表时,为什么必须指定表空间?其中,“报表、开发、临时性统计(即,除通过版本正式上线外)”人员建表时,必须分别放入三个专用的空间,它们的名字分别是什么?
因为若不指定表空间,ODS就会把数据默认放入“TBS_DIM”中,直接导致生产事故。
专用表空间(报表、开发、临时统计)的名称分别是:TBS_BB_01;TBS_KF_01;TBS_TJ_01。涉及此类应用的人必须放入专用表空间,不得乱放,也不得忘记指定表空间。例子,create table aa (……) IN TBS_TJ_01 ;
11. DROP或DELETE全表数据前,必须先执行什么语句才能释放空间?为什么部分命令将表的数据删除或压缩后,数据库的空间不释放?
问题一:在执行DROP或DELETE全表数据前,请务必先执行可立即释放表空间的清空表语句,语法:alter table xxxx activate not logged initially with empty table;
问题二:因为DROP/DELETE/REORG不会立即释放数据库空间,这些命令要在该空间的所有数据库链接同时断开后才能释放。
12. 为什么用LIKE、AS命令建表时,容易发生节点空间偏移,还把TBS_DIM表空间给涨爆了?
以下两种方法均可快速创建表,但是,他无法继承源表的partitioning key 和 表空间等信息,因此,很危险:
create table MAP_ACCT_ITEM_TYPE_ID4_MULTI_bak_20110602 like MAP_ACCT_ITEM_TYPE_ID4_MULTI;
或者
create table MAP_ACCT_ITEM_TYPE_ID4_MULTI_bak_20110602 as (select ACCT_ITEM_TYPE_ID4,ACCT_ITEM_TYPE_DESC4,ACCT_ITEM_TYPE_MKTID3 from MAP_ACCT_ITEM_TYPE_ID4_MULTI) with no data;
为此,需务必在以上SQL语句中补充相关信息。例如,
create table MAP_ACCT_ITEM_TYPE_ID4_MULTI_bak_20110602 like MAP_ACCT_ITEM_TYPE_ID4_MULTI in tbs_tj_01 partitioning key(ACCT_ITEM_TYPE_ID4) NOT LOGGED INITIALLY ……;
13. 系统表syscat.tables的以下常用字段的含义是什么?要看到某个表的这些字段信息,需要先运行什么命令?其中,常用语句和字段:select owner,definer,tabname,CARD ROWS,FPAGES,tbspace,STATS_TIME,CREATE_TIME,COMPRESSION,AVGROWCOMPRESSIONRATIO AVG from syscat.tables where tabname like 'DS%201101‘
问题一:常用字段:CARD:行数(数量级无问题,不完全精确);FPAGES:实际占用页面数;tbspace :表空间;STATS_TIME:runstats统计更新该表的时间;CTIME:表的创建时间; 其他的COMPRESSION、AVGROWCOMPRESSIONRATIO:详见压缩相关说明。
问题二:查看该表相关字段信息前,需要先运行runstats命令,语法详见runstats的问答。
14. 为什么要做表的数据重组(压缩)reorg?ODS的哪些情况下需要尽快执行reorg?如何查看表的实际压缩比例?
问题一:reorg的作用:1)空间方面,压缩表所占用的存储,2)性能方面,降低SELECT该表所使用的IO量,从而提升取数性能。
问题二:ODS需要尽快执行REORG的情况:
1)多次访问的表:例如,前台经常访问的结果表;后台处理中,经常使用的表
2)数据变动量较大的表:例如,月初全量修复的表;每个账期插入大量数据的ST表
3)数据冗余量较大宽表:特别是有中文字段冗余的表
问题三:系统表syscat.tables的字段AVGROWCOMPRESSIONRATIO:实际压缩比例
15. 表数据重组(压缩)reorg命令的两种常用格式?为什么在RAPID SQL工具中执行报错?
格式一:db2 "reorg table TBOWNER.DM_CHN_CUST_GRP_20100423 resetdictionary"(强制新字典参数,可选)
格式二:db2 "reorg table TBOWNER.DS_ACT_ACCT_ITEM_AGG_201005 allow read access " (建议前台表使用此格式)
为什么在RAPID SQL工具中执行报错:因为reorg命令的执行需要通过CRT TELENET工具
16. 为什么有些表执行reorg命令后,实际压缩比例还是0,是不是需先确保一个属性?如何在建表语句中指定该属性?若建表中未指定,如何调整?如何查看某个表的该属性?
问题一:reorg命令前:需确保该表的COMPRESS YES,否则,压缩不起作用。
问题二:建表语句中:CREATE TABLE table_name( . . .) COMPRESS YES;
问题三:建表后的调整:ALTER TABLE tablename COMPRESS YES;
问题四:系统表syscat.tables的字段COMPRESSION:是否可压缩(R为可压缩)
17. 为什么要更新表的统计信息runstats?哪些情况下需要对表做runstats?
问题一:作用:用来更新数据库对象的状态信息(例如,系统表syscat.tables),这对优化器生成最优的执行计划至关重要,也便于查看该表的常用信息。
问题二:在以下三种情况下,必须尽快执行该表的runstats命令:
1)在对table进行reorg后:若在reorg后不执行runstats,则只起到对空间的压缩作用,而难以通过降低IO来提升性能;
2)当表中的数据发生了比较大(20%以上)变化后;
3)在给表创建一个index后。
18. runstats命令的两种常用格式?为什么在RAPID SQL工具中执行报错?其中,哪种情况建议采用抽样10%的统计信息更新方式?
格式一:对全表做统计更新:db2 " runstats on table tbowner.ST_CUST_INTEGRAL_ODS_GRADE_201002 "
格式二:抽样10%做统计更新:db2 "runstats on table tbowner.DS_ACT_ACCT_ITEM_AGG_201005 allow write access tablesample system (10) "
问题二:runstats命令的执行需要通过CRT TELENET工具
问题三:抽样语法的适合场景:大表、且仅需大致估算系统表的信息,因其运行效率比全表统计更新提升5倍以上。
19. 为什么在连接数据库后,必须在执行SQL后尽快断开数据库链接?其中,RAPID SQL工具和CRT TELENET工具要如何才能真正的断开数据库连接?
问题一:ODS数据库的最大并发连接数有限制,该连接会占用系统资源,为此,需及时断开数据库连接。
问题二:RAPID SQL工具断开数据库连接的方法,如下图:请务必点击 左上角Disconnect按钮;或彻底关闭 RAPID SQL工具客户端。
CRT TELENET工具断开数据库连接的方法,如下图:运行 db2 terminate命令;或彻底关闭客户端。
20. 为什么“调度依赖不完整”和“RAPID SQL工具的数据库连接不断开”会导致EDA程序时常报 “锁等待超时”的生产故障?
1)调度依赖不完整:由于两个程序对应的调度未建依赖,导致两个调度在存在同时运行的隐患。为此,创建调度流程过程中,务必建立完整的依赖。
2)RAPID SQL工具的数据库连接不断开:由于该工具提交的select语句会导致给对应的表添加一把读锁,在该连接断开前将不会释放,若当晚有程序需要对该表进行更新,则会报“锁等待超时”错误。为此,使用RAPID SQL工具时,务必随时断开数据库连接。
21. 为什么营维支撑系统的前端表要使用分区表?建表语法是什么?判断是不是分区表的方法?如果发现分区表坏了后,咋个办?
问题一:分区表的作用:相当于按分区键分为多个表,将数据分布到多个表空间,从而提高IO并行。
问题二:建表语法:CREATE TABLE TBOWNER.DS_CHN_PRD_SERV_COM_03_20100821 LIKE MODEL.DS_CHN_PRD_SERV_COM_03_YYYYMMDD IN TBS_DM_04,TBS_DM_03,TBS_DM_02 INDEX IN TBS_INDEX_01 COMPRESS YES DISTRIBUTE BY HASH (GRID_ID) NOT LOGGED INITIALLY PARTITION BY RANGE(AREA_ID) ( STARTING MINVALUE, STARTING 12 ENDING 70 EVERY 1 , ENDING MAXVALUE)
问题三:判断是否为分区表的方法:系统表syscat.tables的字段tbspace:为空,则为分区表
问题四:首先,提取分区表建表脚本:例如,[ods_db1] /home/odsrun/gj $ db2look_tbowner.ksh -t DS_CHN_ACT_SERV_ACCT_ITEM_MKT_01_201103 ;然后,执行提取出来的脚本即可。特别说明:通过“Quest Central”工具无法提取脚本或所在空间 。
22. 为什么ODS大部分情况下,使用表的锁(LOCK)为“表级”?另外,“行级”锁用于那些场合?指定表的锁(LOCK)类型的语句?
表级:在EDA大部分情况下使用表级,因为,一是多数表的数据量比较庞大,如果行级锁会消耗系统过多的资源,造成数据库性能下降,二是数据仓库系统的不需要支持很高的并发
行级:如果是前台频繁更新的表,则务必改为行级LOCKSIZE ROW。
语句:ALTER TABLE DEV.TJ07_YN_SERV_ACC_NBR_REL_200708 LOCKSIZE TABLE;
23. 在ODS中,为什么大部分表不需要建索引?在哪些场合才有必要建索引? 哪些字段不适合建索引?
问题一:因为每个表均要指定分区键(PARTITIONING KEY),若尽量将需要进行全表扫描的字段(用于查询条件、或与其他表关联的字段)纳入分区键中,便可以不用额外建索引了。
问题二:表的分区键无法囊括的字段,且需要用于作为查询条件、或与其他表关联的字段。
问题三:不适合建索引的字段: 分区键中的字段;数据值特别少的字段,如,状态、客户类型等。
24. 表的APPEND ON 属性是什么意思?如何设置这个属性?
APPEND ON 属性含义:当表中数据被delete删除时,空间并不会释放,而是在该行原来的位置做个“DELETED”的标志,表示该空间可以被重用。当DB2执行INSERT操作时,会扫描整个表的空闲空间并将新行置入空槽。而如果我们启用了append on特性,那么当插入新行时,DB2就不必搜索空槽再插入,而是直接插入到表的最后。这适合用于大批量追加 插入的一些ST表。如果启用这种特性,需考虑及时reorg表。
设置此属性的语法:ALTER TABLE DEV.TJ07_YN_SERV_ACC_NBR_REL_200708 APPEND ON;
25. 综合考虑一个表的常用属性后,一个完整的建表SQL语法示例?例如,
CREATE TABLE DEV.TJ07_YN_SERV_ACC_NBR_REL_200708 (
AREA_ID DECIMAL(9,0) ,
ACCT_ID DECIMAL(12,0) ,
SERV_ID DECIMAL(12,0) NOT NULL ,
CUST_ID DECIMAL(12,0) NOT NULL ,
ACC_NBR VARCHAR(20) ,
PRODUCT_ID DECIMAL(9,0)
)
PARTITIONING KEY (SERV_ID)
IN TBS_KF_01 INDEX IN TBS_INDEX
NOT LOGGED INITIALLY COMPRESS YES;
ALTER TABLE DEV.TJ07_YN_SERV_ACC_NBR_REL_200708 APPEND ON;
ALTER TABLE DEV.TJ07_YN_SERV_ACC_NBR_REL_200708 LOCKSIZE TABLE;
26. 建表、删表操作可不可以在程序中动态执行?一般哪个时候执行?
不能在程序中动态执行建表、删表操作:因为建表过程中会锁系统表,容易与其他操作冲突。
若是套表,需提交维护人员配置后在晚上集中执行;若是非套表,一次性建好后,就不应该频繁删除、重建。
27. 数据库的表张数太多,对性能有木有影响?列举哪些措施降低表的张数?
有影响:截止2011年7月,ODS拥有4万张表,系统字典表太大,所有SQL的执行计划等均会首先访问系统字典表,为此,系统整体性能就会急剧下降。
降低表张数的措施:例如,
1)程序中,减少日套表,将需要保留时间超过7天以上的日表归档为月表
2)及时删除(DROP)临时性建表
……
28. 如果嫌dbpartitionnum函数运行速度太慢,有木有快速、大致估算某个表的各节点空间偏移情况的语句?为此,如果发现一个空间的2个节点严重偏移(8%以上),如何才能通过快速、批量运算,轻松揪出是哪些表的分区键指定得有问题?
问题一:有系统表办法,语法例如:SELECT DBPARTITIONNUM,DATA_OBJECT_P_SIZE FROM TABLE (SYSPROC.ADMIN_GET_TAB_INFO('TBOWNER', 'AD_ACT_SERV_ACCT_UNIQUE_DETAIL')) AS T
问题二:快速找出导致某个表空间中2个节点严重偏移的表的步骤:
首先,假设该表空间的0和6是最大和最小的2个节点ID,通过运行以下SQL产生语句。
select 'insert into gj_temp1 SELECT '''||name||''', DBPARTITIONNUM,data_object_p_size FROM TABLE (SYSPROC.ADMIN_GET_TAB_INFO('''||trim(creator)||''','''|| ''||name||''')) AS T where DBPARTITIONNUM in (0,6);'
from sysibm.syscat.tables where tbspace ='TBS_DW_02' ;
然后,批量运行这些语句。
最后,通过以下执行以下语句查看罪魁祸首。
select name,d1,d3,d1-d3 aa from
(select name,
sum(case when DBPARTITIONNUM=0 then value(data_object_p_size,0) else 0 end) d1,
sum(case when DBPARTITIONNUM=6 then value(data_object_p_size,0) else 0 end) d3
from gj_temp1
group by name
) dd where abs(dd.d1-dd.d3)> 100000
其中,表gj_temp1的结构如下:
create table gj_temp1
(name varchar(100),
展开阅读全文