达梦数据库DM8慢SQL追踪及优化分析步骤

发布于:2022-11-02 ⋅ 阅读:(946) ⋅ 点赞:(0)

一、配置慢sql追踪的日志记录

1. 修改dm.ini,开启sql日志

SVR_LOG_NAME  = SLOG_ALL

SVR_LOG   = 1

2. 与dm.ini同一目录下,创建sqllog.ini,并重启数据库服务。自此所有操作sql日志将记录在/dmdata/dmlog目录下

BUF_TOTAL_SIZE          = 10240         #SQLs Log Buffer Total Size(K)(1024~1024000)
BUF_SIZE                = 1024          #SQLs Log Buffer Size(K)(50~409600)
BUF_KEEP_CNT            = 6             #SQLs Log buffer keeped count(1~100)

[SLOG_ALL]
    FILE_PATH    = /dmdata/dmlog
    PART_STOR    = 0
    SWITCH_MODE  = 2
    SWITCH_LIMIT   = 256
    ASYNC_FLUSH   = 1
    FILE_NUM = 1024
    ITEMS    = 0
    SQL_TRACE_MASK  = 1
    MIN_EXEC_TIME = 1
    USER_MODE   = 2
    USERS = ***

3. 捕获应用系统运行一段时间后,从sql日志中过滤出大于1秒的查询sql,写入到/tmp/slow.log

cd /dmdata/dmlog

more *.log|grep 'SEL'|grep -E 'EXECTIME: [0-9]{4,}' >/tmp/slow.log

二、慢SQL优化分析步骤

1. 从中拿出一个慢sql,sql耗时15.8秒,通过达梦管理工具作进一步分析,如下

2022-07-xx 17:35:40.253 (EP[0] sess:0x7ef908009280 thrd:9189 user:xx trxid:48524724 stmt:0x7ef908034a78 appname:manager.exe ip:::ffff:172.x.x.x) [SEL] select * from edicodedata where codemapname in ( select code from edicodesql where uptype in('标准接口')) EXECTIME: 15792(ms) ROWCOUNT: 100(rows).

2. 达梦管理工具通过explain查看sql执行计划,可以看到,主要耗时在全表扫描edicodedata,同时收集到以上sql中edicodedata数据量为5000万条,edicodesql数据量为1000条。二表关联方式是右半哈希连接

 3. 同时,开启ENABLE_MONITOR,可以进一步定位性能问题

SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1)

4. 手动运行一次sql后,获取执行号15668424

5.  调用et系统函数,查看该sql各步骤的实际耗时。图中可以看到主要耗时在于最后一条 CSCN2,即全表扫描,占总耗时的96.97%

SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1)
CALL ET(15668424);

 6. 由于edicodedata表有对codemapname列建立索引,但CBO未选用该索引,并且从第5点图中可以看到两个数据量悬殊的表间采用hash join关联,这显示不合适,正常情况下应采用以小表为驱动表的嵌套循环方式,效率会更高。

7. 同时我们在sql外层加了count(1),发现执行计划改变,并且查询效率非常高,如下图,符合我们的分析预期,走的是nest loop,同时使用了edicodedata表的索引。

 8. 接着经过反复验证,最终通过加HINT /*+ enable_hash_join(0)*/,强制二表关联走nest loop,实现sql优化,最终耗时降到5ms。

 


网站公告

今日签到

点亮在社区的每一天
去签到