达梦存储过程性能问题定位
在达梦数据库中可以通过V$DMSQL_EXEC_TIME和debug方式来定位存储过程存在的性能问题,但V$DMSQL_EXEC_TIME往往定位比较粗糙,没法定位到存储过程中sql的执行时间,而debug可以点位具体某段sql,但如果存储过程里面有大量游标,参数变量值很多的情况下,debug调试也花费大量时间,下面介绍使用日志表来排查存储过程哪些地方耗时较长。
示例如下:存储过程调用需要46分钟
存储过程如下:游标依次获取表中唯一的fid,将fid值传入到3个存储过程调用。
CREATE OR REPLACE PROCEDURE "TEST"."P_TEST" as
declare
V_FID TESTA.FID%type;
cursor c_cursor is
select distinct(FID) from TESTA;
begin
open c_cursor;
fetch c_cursor into V_FID;
while c_cursor %found loop
call P_TEST1(V_FID);
call P_TEST2(V_FID);
call P_TEST3(V_FID);
fetch c_cursor into V_FID;
end loop;
close c_cursor;
end;
如下查询,表中含有211个不同的FID,需要循环211次
创建日志表,根据自己的爱好及实际情况创建字段
CREATE TABLE dmlog (name1 VARCHAR(20),name2 VARCHAR(20),name3 DATETIME)
创建日志表之后,将程序每个步骤的前后执行时间写入到日志表,如下所示:
重新执行存储过程,执行完之后查看日志表
从上可以看到,基本都是stp2到stp3之间的P_TEST2耗时比较久,存储过程如下:
单独查询需要7s,慢在排序
在t1的A字段建立降序索引消除排序
CREATE OR REPLACE INDEX "TEST"."IX_T1_A" ON "TEST"."T1"("A" desc)
查询执行时间减少到2毫秒
在dmlog日志表里面看到,有些参数在stp3和stp4之间的P_test3执行也比较慢
p_test3存储过程如下:
单独查询需要9s,慢在全表扫描,
在fid字段建立索引
CREATE index idx_testa_fid on testa(fid);
索引创建之后执行时间3s,还是比较慢,慢在回表
建立组合索引消除回表,执行时间显著减少
CREATE or REPLACE index idx_testa_fid on testa(fid,SNo,FAcct,Balance,Available,Income);
优化之后,存储过程执行由46分钟减少到5分钟
查看dmlog日志,大部分执行都非常快
如下两个参数在调用p_test3时耗时较长
将参数带入进去查询,执行计划正常
原因是该表数据分布不均衡,当fid为123456,123006时,数据量大导致insert需要比较长的时间