- 浏览: 472162 次
-
文章分类
最新评论
-
datawarehouse:
来学习了。
什么是informatic? -
nange223:
感谢分享,学习了
一些数据库监控,优化,管理工具 -
pianxibin:
ertrth thr dj dyj
一些数据库监控,优化,管理工具 -
gekky6:
多谢分享,学习下
一些数据库监控,优化,管理工具 -
lqlein:
好好学习学习
一些数据库监控,优化,管理工具
索引和表的维护
重新组织索引
随着数据的不断删除,插入和更新,索引页会变得越来越零散,索引页的物理存储顺序不再匹配其逻辑顺序,索引结构的层次会变得过大,这些都会导致索引页的预读取变得效率低下。因此,根据数据更新的频繁程度需要适当的重新组织索引。可以使用 REORG INDEXES 命令来重新组织索引结构,也可以删除并重新创建索引达到相同的目的。同样的,对表进行重新组织也会带来性能的改善。
重新组织某一个表的所有索引的命令如下:REORG INDEXES ALL FOR TABLE table_name。
重新组织一个表的数据的命令如下,在下面的命令还可以为其指定一个特定的索引,REORG 命令将会根据这个索引的排序方式重新组织该表的数据。
REORG TABLE table_name INDEX index_name。
重新收集表和索引的统计信息
和在2.1中提到的原因类似,当一个表经过大量的索引修改、数据量变化或者重新组织后,可能需要重新收集表以及相关索引的统计信息。这些统计信息主要是关于表和索引存储的物理特性,包括记录数目,数据页的数目以及记录的平均长度等。优化器将根据这些信息决定使用什么样的存取计划来访问数据。因此,不能真实反映实际情况的统计信息可能会导致优化器选择错误的存取计划。收集表及其所有索引的统计信息的命令如下:RUNSTATS ON TABLE table_name FOR INDEXES ALL。
上述两个命令具有复杂的参数选择,用户可以参阅DB2 Info Center来根据实际情况使用这两个命令。
修改查询
合理使用NOT IN和NOT EXISTS
一般情况下NOT EXISTS具有快于 NOT IN 的性能,但是这并不绝对。根据具体的数据情况、存在的索引以及查询的结构等因素,两者会有较大的性能差异,开发人员需要根据实际情况选择适当的方式。
譬如下面的查询:
清单10. 查询示例
表结构:temp.customer(cust_num) 主键:cust_num 表结构:temp.contact(cnt_id,cust_num) 主键:cnt_id 表结构:temp.contact_detail(cnt_id,address,phone) 主键:cnt_id 查询 : select cust_num from temp.customer cust where not exists (select 1 from temp.contact cont here cust.cust_num = cont.cust_num) |
此查询用来列出所有不存在联系人的客户。对于这样的需求,开发人员会最自然的写出清单 10 中的查询,的确,对于大部分情况它具有最优的性能。该查询的查询代价为 178,430 timerons。让我们再来看看使用 NOT IN 后查询的总代价,请看清单 11。
清单11. 查询示例
查询: select cust_num from temp.customer cust where cust.cust_num not in (select cont.cust_num from temp.contact cont) 代价:12,648,897,536 timerons |
可以看到 NOT EXISTS 的性能要比 NOT IN 高出许多。NOT IN 是自内向外的操作,即先得到子查询的结果,然后执行最外层的查询,而 NOT EXISTS 恰好相反,是自外向内的操作。在上述例子中,temp.contact 表中有 65 万条记录,使得 10.2 查询中的 NOT IN 列表非常大,导致了使用 NOT IN 的查询具有非常高的查询代价。下面我们对 10.1 和 10.2 的查询进行修改,将 temp.contact 表中的记录限制到 100 条,请看下面的查询:
清单12. 查询示例
查询: select cust_num from temp.customer cust where not exists (select 1 from temp.contact cont here cust.cust_num = cont.cust_num and cont.cnt_id < 100) 代价:42,015 timerons |
清单13. 查询示例:
查询: select cust_num from temp.customer cust where cust.cust_num not in (select cont.cust_num from temp.contact cont where cont.cnt_id < 100) 代价:917,804 timerons |
从 12 和 13 中可以看出 NOT EXISTS 的查询代价随子查询返回的结果集的变化没有大幅度的下降,随着子查询的结果集从 65 万下降到 100 条,NOT EXISTS 的查询代价从 178,430 下降到 42,015,只下降 4 倍。但是 NOT IN 的查询代价却有着极大的变化,其查询代价从 12,648,897,536 下降到 917,804,下降了 13782 倍。可见子查询的结果集对 NOT IN 的性能影响很大,但是这个简单的查询不能说明 NOT EXISTS 永远好于 NOT IN,因为同样存在一些因素对 NOT EXISTS 的性能有很大的影响。我们再看下面的例子
清单14. 查询示例
查询: select cust_num from temp.customer cust where not exists (select 1 from temp.contact cont where cust.cust_num = cont.cust_num and cont.cnt_id in (select cnt_id from temp.contact_detail where cnt_id<100)) 代价:5,263,096 timerons |
清单15. 查询示例
查询: select cust_num from temp.customer cust where cust_num not in (select cust_num from temp.contact cont where cont.cnt_id in (select cnt_id from temp.contact_detail where cnt_id<100)) 代价:4,289,095 timerons |
在上面的例子中,我们只是对查询增加了一个小改动,使用一个嵌套查询限制了在 temp.contact 中扫描的范围。但是在这两个新的查询中,NOT IN 的性能却又好于 NOT EXISTS。NOT EXISTS 的代价增加了 125 倍,而 NOT IN 的代价却只增加了 4 倍。这是由于 NOT EXISTS 是自外向内,嵌套查询的复杂度对其存在较大的影响。因此在实际应用中,要考虑子查询的结果集以及子查询的复杂度来决定使用 NOT EXISTS 或者 NOT IN。对于 IN,EXISTS 和 JOIN 等操作,大多数情况下 DB2 优化器都能形成比较一致的最终查询计划。
合理使用子查询减少数据扫描和利用索引
某些情况下可以将查询中的某一部分逻辑提取出来作为子查询出现,能够减少扫描的数据量,以及利用索引进行数据检索。请看清单 16 中的查询:
清单 16:
索引:temp.cust_i1 on temp.customer(add_date) temp.order_i1 on temp.order(sold_to_cust_num) temp.order_i2 on temp.order(add_date) 查询: select cust.cust_num from temp.customer cust left join temp.order ord on cust.cust_num = ord.sold_to_cust_num where cust.add_date > current timestamp - 2 months or ord.add_date > current timestamp - 2 months |
上面的查询用来选择所有两个月内新增加的用户以及在两个月内定购了产品的用户。从图 10.a 的查询计划中可看出没有任何索引被使用。
图 10. 查询计划
使用子查询对该查询重新改写后,请看清单 17:
清单17.
查询: with tmp as( select sold_to_cust_num from temp.order where add_date > current timestamp - 2 months) select cust.cust_num from temp.customer cust where cust.add_date > current timestamp - 2 months or cust.cust_num in (select sold_to_cust_num from tmp ) |
在清单 17 的查询中,我们使用子查询预先限定了要扫描 temp.order 表中的记录数目,而不是像清单 16 中的查询那样对 temp.order 表进行全表扫描。同时,在预先限定数据范围的时候,能够利用 temp.order_i2 索引。请看其查询计划,如图 10.b。可以看到查询代价有大幅度下降。其实,即使没有 temp.order_i2 索引,修改后的查询也仍然由于前者,因为它预先限定了数据的扫描范围,也减少了后续连接处理的数据量,请看图 10.c。
重新排列各个表的连接顺序,尽量减小中间结果集的数据量
一般情况下,DB2 会根据各表的 JOIN 顺序自顶向下顺序处理,因此合理排列各表的连接顺序会提高查询性能。譬如清单 18 中的查询:
清单18.
查询: select cust.cust_name, ord.order_num, cnt.cnt_first_name from temp.customer cust left join temp.order ord on cust.cust_num = ord.sold_to_cust_num join temp.contact cnt on cust.cust_num = cnt.cust_num where cnt.mod_date > current timestamp - 1 months |
清单 18 中的查询用来选择出所有最近一个月内修改过联系人信息的客户的订单信息。此查询会按照链接的顺序先将 temp.customer 表和 temp.order 表进行 LEFT JOIN,然后使用结果集去 JOIN temp.contact 表。由于该查询使用了 LEFT JOIN,因此在生成中间结果集的时候不会有任何记录会被过滤掉,中间结果集的记录数目大于等于 temp.customer 表。了解到了 DB2 是如何解释和执行这样的查询后,很自然的我们就会想到将 JOIN 提前。请看清单 19。
清单19.
查询: select cust.cust_name, ord.order_num, cnt.cnt_first_name from temp.customer cust join temp.contact cnt on cust.cust_num = cnt.cust_num left join temp.order ord on cust.cust_num = ord.sold_to_cust_num where cnt.mod_date > current timestamp - 1 months |
图 11.a 和图 11.b 分别为清单 18 和 19 的查询的存取计划。在 19 的查询中,在形成中间结果集的时候也应用到了 WHERE 语句中的条件,而不是在所有 JOIN 都结束以后才被应用去除记录的。
图11. 查询计划
另外,在修改查询尽量减少中间结果集的记录条数的时候还要考虑中间结果集的数据总量,譬如中间结果集需要保存的每条记录的长度。如果我们把 JOIN temp.contact 提前以后,由于中间结果集需要保存过多的 contact 表的列反而使得结果集的数据总量变大,可能不会带来性能上的改善。
使用UDF代替查询中复杂的部分
由于 UDF 是预先编译的,性能普遍优于一般的查询,UDF 使用的存取计划一经编译就会相对稳定。笔者在工作中曾多次发现,使用 UDF 代替查询或者视图中的复杂部分会提高几倍甚至几十倍的性能,主要原因是迫使 DB2 使用指定的存取计划来充分利用 index 或者调整其访问过程(如 Join 顺序, Filter 位置等)。使用 UDF 进行优化的基本思路是,将复杂查询分解为多个部分执行,针对每个部分优化处理,将各部分组合时能够避免存取计划的一些不必要变化,优化整体性能。譬如清单 20 中的查询:
清单20.
查询:select * from temp.customer where cust_num in ( select distinct sold_to_cust_num from temp.order where add_date > current timestamp - 2 months union select distinct cust_num from temp.contact where add_date > current timestamp - 2 months ) |
这个查询会导致优化器生成比较复杂的查询计划,尤其是 temp.customer 是一个比较复杂的视图的时候。这种情况下我们可以通过创建 UDF,将其分步执行:先执行子查询获得 cust_num 值的列表,然后执行最外层的查询。下面的例子是通过 UDF 对清单 20 的查询的改写:
清单21.
CREATE FUNCTION temp.getCustNum(p_date timestamp) RETURNS TABLE (cust_num CHARACTER(10)) RETURN select distinct sold_to_cust_num from temp.order where add_date > p_date union select distinct cust_num from temp.contact where add_date > p_date; select * from customer where cust_num in ( select cust_num from table(temp.getCustNum(current timestamp - 2 months)) tbl ) |
改写前后的查询代价分别是 445,159.31 和 254,436.98。当面对比较复杂的查询时考虑使用 UDF 将其拆分为多步执行常常会带来意想不到的效果。在实际的项目中,如果数据处理和查询调用是包含在其他应用程序中如 Unix 脚本,Java 程序等,同样可以考虑采用分步数据处理的方式来调用数据库,以优化应用性能。
总结
本文主要介绍了如何使用 DB2 提供的各种查看存取计划的工具,并根据作者在 DB2 方面的开发经验总结了一些提高查询性能的方法和技巧。如果能够有效地利用 DB2 提供的各种工具,理解 DB2 中索引的结构,以及查询将如何被解释,数据库开发人员可以更好的提高查询性能来满足需求
发表评论
-
DB2常用学习参考网站
2009-09-04 10:38 1162http://www.ibm.com/developerwor ... -
DB2错误信息(按sqlcode排序)
2009-08-18 15:01 2638DB2错误信息(按s ... -
修改表列的类型
2009-08-13 17:50 988修改表列的类型: alter table dw. ... -
DB2常用函数与Oracle比较
2009-07-29 14:01 1545http://blog.csdn.net/xiaosheng2 ... -
DB2 SQL0802N错误(发生算术溢出或其他算术异常)
2009-07-27 16:41 5938(1) SELECT claimno, ... -
深入优化DB2 数据库的五个最佳实践 (1)
2009-07-10 16:14 1105http://industry.ccidnet.com/ ... -
了解DB2数据库优化的几条策略
2009-07-09 16:57 9901、 对后续用到的表建立索引(注意在插入数据之前建立或者在插入 ... -
提高DB2查询性能的常用方法(二)
2009-06-27 16:31 2260下面我们将从三个方面介绍一些提高查询性能的方法。 创建索 ... -
提高DB2查询性能的常用方法(一)
2009-06-27 16:30 1628http://www.searchdatabase.com.c ... -
SQL语句优化DB2应用程序性能(四)
2009-06-27 16:06 15716、指定FOR FETCH ONLY子句 如果不想更新那 ... -
SQL语句优化DB2应用程序性能(三)
2009-06-27 16:05 1739如果在DECLARE CURSOR语句中指定FOR UPDA ... -
SQL语句优化DB2应用程序性能(二)
2009-06-27 16:05 1241剩余谓词是用关系 ... -
SQL语句优化DB2应用程序性能(一)
2009-06-27 16:04 1130当我们设计一个新的或分析一个现存的系统时,其中所要考 ... -
sql的性能如何调整
2009-06-27 15:27 948http://www.alixixi.com/Dev/DB/D ... -
DB2学习笔记
2009-06-18 11:22 977http://blog.ixpub.net/html/37/8 ...
相关推荐
基于万能逼近原理的自适应模糊控制算法在多自由度AUV运动控制中的应用与抗干扰补偿Simulink仿真研究,自适应模糊控制算法的万能逼近原理与多自由度AUV运动控制的抗干扰补偿技术——基于Simulink的仿真研究,万能逼近原理自适应模糊控制算法的多自由度AUV运动控制抗干扰补偿simulink仿真 ,核心关键词:万能逼近原理; 自适应模糊控制算法; 多自由度AUV运动控制; 抗干扰补偿; Simulink仿真。,基于万能逼近的模糊控制算法多自由度AUV抗干扰补偿Simulink仿真
deepseek最新资讯、配置方法、使用技巧,持续更新中
deepseek最新资讯、配置方法、使用技巧,持续更新中
结合扩展卡尔曼滤波与滑模观测器的策略:优化电角度估计,反电势波形逼近完美正弦波,结合扩展卡尔曼滤波与滑模观测器的反电势波形优化:正弦波形展现近乎完美精度,电角度估算与实际应用差异微小,扩展卡尔曼滤波与滑模观测器的结合,反电势波形近乎完美的正弦波形,观测器估算转子电角度与实际电角度相差0.3弧度左右,转速跟随效果较好。 ,核心关键词:扩展卡尔曼滤波; 滑模观测器; 反电势波形; 转子电角度估算; 转速跟随效果。,卡尔曼滑模观测器:优化正弦波转子角度与转速估算
毕业设计_基于springboot+vue的**学生公寓管理系统**【源码+sql+可运行】【**50217**】.zip 全部代码均可运行,亲测可用,尽我所能,为你服务; 1.代码压缩包内容 代码:springboo后端代码+vue前端页面代码; 脚本:数据库SQL脚本 效果图:运行结果请看资源详情效果图 2.环境准备: - JDK1.8+ - maven3.6+ - nodejs14+ - mysql5.6+ - redis 3.技术栈 - 后台:springboot+mybatisPlus+Shiro - 前台:vue+iview+Vuex+Axios - 开发工具: idea、navicate 4.功能列表 - 系统设置:用户管理、角色管理、资源管理、系统日志 - **业务管理:业务管理:公寓信息、房间信息、入住记录、学生信息** 3.运行步骤: 步骤一:修改数据库连接信息(ip、port修改) 步骤二:找到启动类xxxApplication启动 4.若不会,可私信博主!!!
1、文件内容:xorg-x11-server-source-1.20.4-29.el7_9.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/xorg-x11-server-source-1.20.4-29.el7_9.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
1、文件内容:yum-plugin-ps-1.1.31-54.el7_8.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/yum-plugin-ps-1.1.31-54.el7_8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
基于模型预测控制(MPC)的无人船与无人车编队一致性协同控制研究(附原文献),基于模型预测控制(MPC)的无人船与无人车编队一致性协同控制研究(附原文献),无人船编队 无人车编队 MPC 模型预测控制 多智能体协同控制 一致性 MATLAB 无人车 USV 带原文献 ,无人船编队; 无人车编队; MPC 模型预测控制; 多智能体协同控制; 一致性; MATLAB; USV; 原文献,无人系统协同控制:MPC模型预测控制下的多智能体编队与一致性研究(原文献支撑)
4套中级通信工程师综合真题及答案(2019,2020,2021,2023),适用于需要考中级通信工程师的人群
deepseek最新资讯,配置方法,使用技巧,持续更新中
基于matlab的锁相环PLL相位噪声拟合仿真代码集合:多个版本建模与仿真,高质量的锁相环PLL仿真代码集合:Matlab与Simulink建模研究,[1]锁相环 PLL 几个版本的matlab相位噪声拟合仿真代码,质量杠杠的,都是好东西 [2]锁相环matlab建模稳定性仿真,好几个版本 [3]锁相环2.4G小数分频 simulink建模仿真 ,PLL; Matlab相位噪声拟合仿真; Matlab建模稳定性仿真; 锁相环2.4G小数分频Simulink建模仿真,MATLAB仿真系列:锁相环PLL及分频器建模仿真
exceptionLogs.zip
基于光伏微网的经济性与并网负荷波动率双目标优化调度策略:蓄电池与V2G协同管理策略仿真研究,MATLAB下光储充微网结合电动汽车V2G的多目标协同调度策略研究:经济性与并网负荷波动性的对比分析,MATLAB代码:考虑V2G的光储充一体化微网多目标优化调度策略 关键词:光储充微网 电电汽车V2G 多目标优化 蓄电池优化 调度 参考文档:《光伏微网下考虑V2G补偿蓄电池容量的双目标优化调度策略》,已经投稿EI会议,中文说明文档可联系我咨询 仿真平台:MATLAB 平台 优势:代码注释详实,适合参考学习,相关成果已经采用,程序非常精品,请仔细辨识 主要内容:过建立光伏微网中以经济性和并网负荷波动率为双目标的蓄电池和V2G的协同调度模型。 采用粒子群算法,对电网、微网调度中心和电动汽车用户三方在无、无序、转移和调度V2G电动汽车负荷四种运行模式下的经济和安全影响进行对比。 最后,根据算例分析,求解四种模式下两级负荷曲线及经济收益表。 对比分析得出,引入V2G可以替代部分容量的蓄电池,使光伏微网在负荷峰谷平抑、三方经济和安全等方面进一步优化。 求解采用的是PSO算法(粒子群算法),求解效果极
javascript 动态网页设计期末大作业(自己手写的,高分期末作业),含有代码注释,新手也可看懂,个人手打98分项目,导师非常认可的高分项目,毕业设计、期末大作业和课程设计高分必看,下载下来,简单部署,就可以使用。该项目可以直接作为毕设、期末大作业使用,代码都在里面,系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值,项目都经过严格调试,确保可以运行! javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期
混合智能体系统编队控制:分布式优化与15异构混合阶的挑战,异构混合阶智能体系统编队控制的分布式优化策略研究,15异构混合阶多智能体系统编队控制的分布式优化(无参考文献) ,核心关键词:15异构混合阶; 多智能体系统; 编队控制; 分布式优化; 无参考文献。,15混合阶多智能体系统编队分布式优化控制
javascript 动态网页设计期末大作业(自己手写的,很适合期末作业),含有代码注释,新手也可看懂,个人手打98分项目,导师非常认可的高分项目,毕业设计、期末大作业和课程设计高分必看,下载下来,简单部署,就可以使用。该项目可以直接作为毕设、期末大作业使用,代码都在里面,系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值,项目都经过严格调试,确保可以运行! javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascrip
X光安检OPIXray数据集已经转换为VOC格式,可直接转换为为YOLO
DataX--Web:图形化界面简化大数据任务管理_datax-web
# 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!