今天看了一篇文章,觉得不管怎么强调sortheap的重要性都不为过。理由我后面肯定会写详细的,这里写记录下,占个位置:
----2007.07.10.00。13(没想到是10号还以为9号呢 ,9号刚过)
========================
感觉学的不是很好,没有达到目标,但还是把这2天学的写上吧 。
1.sortheap在数据库配置说明上是这样的:定义要用于专用排序的专用内存页的最大数目,或者要用于共享排序的共享内存页的最大数目。现在这个项目并没有启动分区并行性,所以此参数只是表示要用于专用排序的专用内存页的最大数目。不知道是我没理解好,还是db2没有说好,其实这个参数还有个很重要的作用:数据库在执行散列连接sql的时候也用到此内存区域。db2 对2个表进行连接的时候,只有3种类型:嵌套,合并,散列。其中散列连接用的最多(我在执行复杂sql的时候是这样的,简单的没有测试过大家可以测试下)。进行散列连接的时候,数据库会把其中一个表的内容复制到sortheap对应的内存中,如果sortheap对应的内存不够大,就会吧余下的数据库复制到临时表空间中。然后进行连接比较。可以想想操作内存和操作硬盘的差别吧,所以我们应尽量大的设置sortheap,使他不溢出到硬盘中,或者很少溢出。(关于上面3中嵌套,合并,散列连接类型,可以看下面的附件,附件中有很详细的说明)
2. 查看是否溢出的方法:
大家执行下面的命令: db2 gen snapshot for db on 数据库名 (这个命令不需要打开db2的快照开关,db2有些默认的快照信息)。在输出的信息中查找下面的信息:
已分配的专用排序堆总数 = 0
已分配的共享排序堆总数 = 0
共享排序堆高水位标记 = 0
总计排序 = 34600
总计排序时间(毫秒) = 35491
排序溢出 = 2384
活动排序数 = 0
和
散列连接数 = 38808
散列循环数 = 0
散列连接溢出数 = 534
小散列连接溢出数 = 1
排序溢出 /总计排序 可以得到溢出比例 (如果溢出比例大于 3 个百分点,那么在应用程序 SQL 中会出现严重的或意外的排序问题。因为正是溢出的存在表明发生了大的排序,所以理想的情况是发现没有排序溢出或至少其百分比小于一个百分点。
如果出现过多的排序溢出,那么“应急”解决方案是增加SORTHEAP的大小。然而,这样做只是掩盖了真实的性能问题。相反,您应该确定引起排序的 SQL 并更改该 SQL、索引或群集来避免或减少排序开销。如果溢出比例大于 5 (作为一种经验之谈),那么每个事务的排序数可能很大。虽然某些应用程序事务执行许多小的组合排序(它们不会溢出并且执行时间很短),但是它消耗了过多的 CPU。当SortsPerTX很大时,按我的经验,这些机器通常会受到 CPU 的限制。确定引起排序的 SQL 并改进存取方案(通过索引、群集或更改 SQL)对提高事务吞吐率是极为重要的。)
散列连接数 就是在执行sql的时候进行散列连接的数目。这里只说下散列循环数 的意义,其他参数的意义在下面的附件中都有很详细的说明: 我在测试的时候,把sortheap设置为16个页,然后执行复杂的sql,散列循环数有值,而且很高。一般看到散列循环数有值就要注意,他说明你的sortheap或者SHEAPTHRES(实例级参数)太低了。现在的测试情况就说明sortheap太低了。另外一种情况SHEAPTHRES太低的原因: SHEAPTHRES已经分配给前面的代理进程了,再有代理进程申请sortheap的时候,SHEAPTHRES已经达到上限了,这个时候db2就会给申请sortheap的进程很小的值,此时代理进程进行散列连接的时候就需要把很多数据放到硬盘上,这个时候就会导致散列循环数值很高,这个时候大家可以增加 SHEAPTHRES进行观察。
3.查看排序溢出的sql方法: 首先打开快照监视器: db2 update monitor switches using sort on statements on ;
然后过段时间(1分钟就可以了)执行 get snapshot for all on 数据库名;
在输出的信息中查找:语句排序溢出 = 1 ,看对应的sql就知道了,对sql的执行计划分析下就明白了。
记得在测试完要关闭 快照开关: db2 update monitor switches using sort off statements off;