在数据库运维场景中,经常会遇到带有绑定变量的 SQL 执行缓慢的问题。要对这类问题进行精准排查与优化,核心前提是获取完整的 SQL 语句以及绑定变量对应的具体参数值。
如果无法直接接触服务器的 SQL 日志文件,达梦数据库提供了内置系统函数可实现该需求。本文将详细介绍如何通过SF_EXTRACT_BIND_DATA和SF_EXTRACT_BIND_DATA_NUM两个函数,查询含有绑定变量的 SQL 及其参数值,为 SQL 优化提供可靠数据支撑。
达梦数据库提供了两个专用系统函数用于解析绑定变量信息,二者配合使用可完整获取绑定变量的个数与具体内容,以下是详细说明。
函数定义
VARCHAR
SF_EXTRACT_BIND_DATA(
binddata varbinary, -- 绑定参数的原始二进制数据
nth integer, -- 参数序号,从1开始递增,不可为0或超出参数总个数
attr integer -- 提取属性标识,仅支持1或2
)
功能说明:获取指定绑定变量的类型或具体内容。
参数补充说明:
attr=1:获取绑定变量的数据类型(小数类型不返回精度和标度信息);
attr=2:获取绑定变量的实际参数内容(运维排查中最常用)。
返回值说明:
若binddata为 NULL 或空值,返回 NULL;
若nth大于实际绑定参数个数但小于等于语句中定义的参数个数,返回字符串 "NO DATA";
若nth<=0或大于语句中定义的参数总个数,直接抛出错误;
若attr不为 1 或 2,直接抛出错误。
函数定义
INT
SF_EXTRACT_BIND_DATA_NUM(
binddata varbinary, -- 绑定参数的原始二进制数据
num int -- 统计类型标识,仅支持1或2
)
功能说明:获取绑定语句中变量的相关个数。
参数补充说明:
num=1:获取实际绑定的参数个数;
num=2:获取绑定语句中定义的参数总个数(运维排查中最常用,确保不遗漏变量)。
返回值说明:返回对应统计类型的整数形式参数个数,若binddata无效则返回 0。
要成功通过上述函数查询绑定变量信息,需要满足以下前提条件:
1.已获取目标 SQL 对应的EXEC_ID(执行 ID),该 ID 可通过达梦其他系统视图(如V$SQL_HISTORY、V$LONG_EXEC_SQLS等)查询获取;
2.SQL 执行前,数据库已配置并启用以下两个监控参数(需拥有管理员权限配置):
ENABLE_MONITOR=1(启用数据库全局监控功能);
ENABLE_MONITOR_BP=1(启用绑定变量监控功能)。
SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
SP_SET_PARA_VALUE(1,'ENABLE_MONITOR_BP',1);
本文核心查询依赖达梦数据库的V$SQL_BINDDATA_HISTORY系统视图,该视图用于存储历史执行 SQL 的绑定变量二进制数据,核心字段说明如下:
EXEC_ID:SQL 执行 ID,作为关联目标 SQL 的唯一标识;
BINDDATA:绑定变量的原始二进制数据,作为两个核心函数的入参。
假设我们已通过其他系统视图获取到目标缓慢 SQL 的EXEC_ID=84330,接下来将通过PL/SQL 块遍历提取该 SQL 对应的所有绑定变量具体值,步骤如下:
3.1 可执行 SQL 代码示例
DECLARE
V_EXEC_ID BIGINT := 84330; -- 目标SQL的EXEC_ID,替换为实际查询到的ID
V_BIND_COUNT INT;
V_VAL VARCHAR(8000);
BEGIN
SELECT SF_EXTRACT_BIND_DATA_NUM(BINDDATA, 2)
INTO V_BIND_COUNT
FROM V$SQL_BINDDATA_HISTORY
WHERE EXEC_ID = V_EXEC_ID;
FOR i IN 1..V_BIND_COUNT LOOP
SELECT SF_EXTRACT_BIND_DATA(BINDDATA, i, 2)
INTO V_VAL
FROM V$SQL_BINDDATA_HISTORY
WHERE EXEC_ID = V_EXEC_ID;
DBMS_OUTPUT.PUT_LINE('BP [' || i || '] = ' || NVL(V_VAL, 'NULL'));
END LOOP;
END;
/
3.2 执行说明
该代码为达梦数据库支持的 PL/SQL 块,可直接在达梦管理工具(DM Manager)、disql 等客户端工具中执行;
执行前需确保客户端已启用DBMS_OUTPUT输出功能(disql 中可执行SET SERVEROUTPUT ON;开启);
若需查询其他 SQL 的绑定变量,仅需修改V_EXEC_ID赋值语句中的数值为目标 SQL 的EXEC_ID即可。
3.3 执行结果示例
执行上述 PL/SQL 块后,将在客户端输出窗口得到如下格式的结果,清晰展示每个绑定变量的序号与具体值:
BP [1] = TEST
BP [2] = 1111
BP [3] = 2222
BP [4] = 3333
BP [5] = 4444
BP [6] = 5555
达梦数据库中,通过SF_EXTRACT_BIND_DATA和SF_EXTRACT_BIND_DATA_NUM两个内置函数,可在不接触服务器 SQL 日志的前提下,提取绑定变量的具体信息;
使用该方法的核心前提是启用监控参数、获取有效EXEC_ID且 SQL 已正常执行;
核心操作是通过 PL/SQL 块循环遍历绑定变量,最终输出每个变量的实际参数值,配合V$SQL_HISTORY等视图可获取完整 SQL,为运维排查与 SQL 优化提供完整数据支撑,适合各类达梦数据库运维场景落地使用。
文章
阅读量
获赞
