ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Oracle SQLT 工具包实战:从10g到19c安装、诊断报告生成与跨版本执行计划对比

Oracle SQLT 工具包实战:从10g到19c安装、诊断报告生成与跨版本执行计划对比 简介这份资源是面向Oracle DBA、系统管理员及数据库性能调优开发者的SQLT工具脚本合集覆盖10g、11g、12c、18c、19c多个版本用于分析SQL执行计划、生成并迁移SQL Profile解决语句执行效率低下、资源消耗过高等问题。压缩包共205个文件以160个sql脚本为主辅以19个pkb与19个pks包体文件、5个txt说明及2个html文档整体约927KB结构紧凑便于按模块查阅。其中coe_xfr_sql_profile.sql可用于跨环境迁移SQL Profile配合SQL Tuning Advisor生成的优化建议帮助读者在开发、测试与生产环境间共享调优成果。目前已有417人学习下载适合需要系统掌握SQL性能诊断与执行计划优化的中高级数据库从业者参考使用。1. 从一份 2020 年的 SQLT 工具包说起它到底能解决什么2020 年 6 月 5 日打包的sqlt_10g_11g_12c_18c_19c_5th_June_2020.zip名字里塞满了 Oracle 数据库的版本号——10g、11g、12c、18c、19c。如果你正在维护一套跨多个版本的 Oracle 环境或者被一个执行计划突然变差的 SQL 折磨过这个包大概率就是你需要的。SQLT 全称 SQLTXPLAIN是 Oracle 官方提供的一套诊断工具集核心能力是围绕一条 SQL 生成一份完整的诊断报告把执行计划、统计信息、对象元数据、系统参数、等待事件等全部打包出来。它解决的不是“SQL 怎么写”的问题而是“这条 SQL 为什么突然变慢、为什么换了执行计划、为什么在 19c 上跑得比 11g 差”这类排查场景。适合的人群很明确DBA、性能优化工程师、以及需要向 Oracle 原厂提交 SR 但被要求提供 SQLT 报告的一线人员。这个包之所以把多个版本放在一起是因为 SQLT 在不同数据库版本上的安装脚本和内部查询有差异一个包覆盖 10g 到 19c省去了到处找对应版本的麻烦。2. SQLT 的安装与版本适配从 10g 到 19c 的落地步骤2.1 解压后先看目录结构别急着跑安装脚本拿到 zip 之后第一步不是直接unzip然后找install.sql。这个包的结构通常是按版本和工具类型分目录的常见做法是先解压到一个独立的目录比如/u01/sqlt_tool然后确认里面有没有sqlt主目录、run目录、以及针对不同版本的sqlplus连接脚本。我一般会先执行unzip -l看一眼文件清单确认没有嵌套压缩包再解压。解压后重点看sqlt/install和sqlt/run两个目录前者是安装脚本后者是生成报告时调用的入口。# 先看压缩包内容确认目录结构 unzip -l sqlt_10g_11g_12c_18c_19c_5th_June_2020.zip | head -50 # 解压到独立目录避免和已有 SQLT 安装冲突 mkdir -p /u01/sqlt_tool cd /u01/sqlt_tool unzip /path/to/sqlt_10g_11g_12c_18c_19c_5th_June_2020.zip # 确认关键目录存在 ls -d sqlt/install sqlt/run sqlt/utl 2/dev/null逻辑说明unzip -l先看清单是为了避免解压出一堆散落文件到当前目录。解压到独立目录是因为 SQLT 安装会在数据库里创建用户和大量对象如果之前装过旧版本混在一起容易出问题。ls -d确认三个关键目录install放安装脚本run放生成报告的脚本utl放一些辅助工具。参数说明-l只列出不解压-d指定解压目标目录。如果你的环境有多个 Oracle Home解压目录不要放在 Oracle Home 下面避免升级或打补丁时被覆盖。2.2 安装 SQLT 到数据库用 sqcreate 还是手动跑脚本SQLT 的安装方式有两种一种是跑sqcreate.sql交互式创建 SQLT 用户和对象另一种是手动创建用户再跑sqlt/install/sqlt_install.sql。常见做法是用sqcreate.sql因为它会帮你处理好表空间、临时表空间、用户权限这些琐事。但这里有个版本坑10g 和 11g 的sqcreate.sql对表空间名称的默认值不一样12c 之后又引入了可插拔数据库的概念如果你在 PDB 里安装连接方式必须用sqlplus / as sysdba先切到 PDB或者直接用 PDB 的服务名连接。-- 以 sysdba 身份连接10g/11g 直接连实例12c 需要指定 PDB -- 10g/11g: sqlplus / as sysdba -- 12c/18c/19c 在 PDB 中安装: sqlplus sys/password//host:port/pdb_service as sysdba -- 执行安装脚本按提示输入 SQLT 用户的密码、默认表空间、临时表空间 sqcreate.sql逻辑说明sqcreate.sql会提示你输入 SQLT 用户的密码、默认表空间、临时表空间、以及是否使用在线模式。在线模式会收集更多信息但耗时更长离线模式快但信息少。第一次安装建议选在线模式后续生成报告时可以用离线模式加速。参数说明默认表空间建议单独建一个比如SQLT_DATA不要用SYSTEM或SYSAUX。临时表空间用默认的TEMP即可。如果数据库是 12c 以上的 PDB务必确认当前会话在正确的容器里否则 SQLT 用户会建到 CDB 根容器后续生成报告时连不上目标 PDB 的对象。2.3 验证安装是否成功三个必须检查的点安装完成后别急着跑报告先做三个检查。第一确认 SQLT 用户能正常连接第二确认sqlt/run目录下的脚本有执行权限第三跑一个最简单的sqltxplain.sql测试一下看能不能生成一份空报告。我见过太多人安装完直接上生产 SQL结果报告生成到一半报错回头查发现是权限没给够。-- 检查 SQLT 用户是否存在且能连接 conn sqlt_user/passwordservice_name select user from dual; -- 检查关键对象是否存在 select object_name, object_type from user_objects where object_name in (SQLTXPLAIN,SQLT$_XPLAIN,SQLT$_SQLDETAILS) order by object_name; -- 检查权限 select privilege from user_sys_privs where privilege like %SELECT ANY DICTIONARY% or privilege like %ADVISOR%;逻辑说明user_objects查三个核心对象SQLTXPLAIN是主包SQLT$_XPLAIN和SQLT$_SQLDETAILS是内部表。如果这三个对象不存在说明安装脚本没跑完。user_sys_privs查系统权限SQLT 需要SELECT ANY DICTIONARY和ADVISOR权限才能收集完整的执行计划和统计信息。参数说明如果查不到SELECT ANY DICTIONARY需要手动授权grant SELECT ANY DICTIONARY to sqlt_user;。ADVISOR权限在 11g 以上是ADVISOR角色的一部分直接grant ADVISOR to sqlt_user;即可。3. 用 SQLT 生成诊断报告从 SQL_ID 到完整分析包3.1 三种生成方式SQL_ID、SQL 文本、AWR 历史SQLT 生成报告有三种入口对应不同的排查场景。第一种是用 SQL_ID适合 SQL 还在共享池里、或者你知道 SQL_ID 的情况。第二种是直接用 SQL 文本适合 SQL 还没执行过、你想先分析的情况。第三种是从 AWR 历史里取适合 SQL 已经不在共享池、但 AWR 里有历史快照的情况。我一般优先用 SQL_ID因为最直接而且能拿到当前的实际执行计划。-- 方式一用 SQL_ID 生成报告 -- 先找到 SQL_ID select sql_id, sql_text from v$sql where sql_text like %你的SQL片段% and rownum 5; -- 然后调用 SQLT 生成报告 sqlt/run/sqltxplain.sql sql_idabc123xyz methodXECUTE -- 方式二用 SQL 文本生成报告 sqlt/run/sqltxplain.sql sql_textselect * from orders where customer_id100 -- 方式三从 AWR 取历史 SQL sqlt/run/sqltxplain.sql sql_idabc123xyz methodAWR逻辑说明method参数控制收集方式。XECUTE会实际执行 SQL 并收集运行时统计适合 SQL 还能跑的情况。AWR从 AWR 快照里取历史信息适合 SQL 已经不在共享池的情况。SQLT是默认方式只收集元数据和执行计划不实际执行。参数说明sql_id是必填method可选。如果 SQL 文本里有特殊字符用双引号包起来。生成报告的时间取决于 SQL 复杂度和数据库负载简单 SQL 几分钟复杂 SQL 可能十几分钟。3.2 报告文件解读从 HTML 主报告到内部表查询SQLT 生成的报告是一个 zip 包里面包含 HTML 主报告、执行计划、统计信息、对象元数据、系统参数等。主报告是sqlt_report.html用浏览器打开就能看。但 HTML 报告有时候信息太多我习惯直接查 SQLT 的内部表比如SQLT$_SQLDETAILS和SQLT$_XPLAIN用 SQL 过滤出关键信息。-- 查最近生成的报告 select sql_id, sql_text, report_name, created from sqlt$_sqldetails order by created desc; -- 查执行计划 select plan_table_output from table(dbms_xplan.display_sqlset(SQLT$_SQLSET, abc123xyz)); -- 查统计信息 select name, value from sqlt$_sqlstats where sql_id abc123xyz order by name;逻辑说明SQLT$_SQLDETAILS存的是每次生成报告的元数据包括 SQL_ID、SQL 文本、报告文件名、生成时间。dbms_xplan.display_sqlset从 SQLT 的 SQLSET 里取执行计划比直接查v$sql_plan更稳定因为 SQLT 会把执行计划快照存下来。SQLT$_SQLSTATS存的是运行时统计比如buffer_gets、disk_reads、elapsed_time。参数说明SQLT$_SQLSET是 SQLT 内部 SQLSET 的名称固定不变。abc123xyz换成你的 SQL_ID。如果查不到统计信息说明生成报告时用了离线模式没有收集运行时数据。3.3 把报告提交给原厂打包和上传的注意事项如果你生成 SQLT 报告是为了提交 SR有几个细节要注意。第一报告 zip 包里可能包含敏感数据比如 SQL 文本里的实际值、对象名称、甚至数据字典信息提交前确认是否符合公司的数据安全要求。第二原厂通常要求提供完整的 zip 包不要只发 HTML 文件因为内部表的数据在 zip 里。第三如果报告太大可以用sqlt/utl目录下的压缩脚本先压缩再上传。# 找到生成的报告 zip 包 ls -lt /u01/sqlt_tool/sqlt/run/*.zip | head -5 # 如果报告太大用 SQLT 自带的压缩脚本 cd /u01/sqlt_tool/sqlt/utl ./sqlt_zip.sh /path/to/report.zip # 确认 zip 包内容完整 unzip -l /path/to/report.zip | grep -E html|xml|txt | head -20逻辑说明ls -lt按时间倒序列出最近的报告 zip 包。sqlt_zip.sh是 SQLT 自带的压缩脚本会重新打包并去掉一些冗余文件。unzip -l确认 zip 包里包含 HTML、XML、TXT 三类文件缺一不可。参数说明sqlt_zip.sh的路径参数是原始报告 zip 的路径。如果原厂要求特定格式比如只接受.zip不接受.tar.gz注意转换。4. 避坑与排查SQLT 安装和生成报告时的血泪经验4.1 坑一12c 以上 PDB 环境装到了 CDB 根容器现象安装脚本跑完了SQLT 用户也建了但生成报告时报错ORA-00942: table or view does not exist查user_objects发现核心对象都不在。原因12c 以上版本如果连接时没有指定 PDB 服务名sqlplus / as sysdba默认连到 CDB 根容器SQLT 用户和对象都建在根容器里。但你要分析的 SQL 在 PDB 里SQLT 查不到 PDB 的数据字典。解决先确认当前容器select sys_context(USERENV,CON_NAME) from dual;。如果返回CDB$ROOT需要切到 PDBalter session set container你的PDB名;然后重新跑安装脚本。或者直接用 PDB 的服务名连接sqlplus sys/password//host:port/pdb_service as sysdba。4.2 坑二10g 环境跑 19c 的安装脚本现象在 10g 数据库上跑sqcreate.sql报错ORA-06550: line X, column Y: PLS-00201: identifier DBMS_SQLTUNE must be declared。原因这个包虽然覆盖 10g 到 19c但安装脚本是分版本的。10g 的DBMS_SQLTUNE包功能有限19c 的脚本里用了 10g 不支持的 API。解决确认sqlt/install目录下有没有按版本分的子目录比如10g、11g、12c。如果有进对应版本目录跑安装脚本。如果没有找 10g 专用的 SQLT 版本不要用这个包里的脚本。4.3 坑三生成报告时 SQL 文本里有绑定变量现象用sql_text方式生成报告报错ORA-00933: SQL command not properly ended或者报告里执行计划是空的。原因SQL 文本里有绑定变量占位符比如:1、:2SQLT 直接拿文本去解析解析不了绑定变量。解决用sql_id方式代替sql_text方式。如果 SQL 还没执行过先用explain plan for跑一遍拿到 SQL_ID再用 SQL_ID 生成报告。或者把绑定变量替换成实际值但注意替换后的 SQL 可能和原 SQL 的执行计划不一样。4.4 坑四报告生成到一半卡住查 v$session 发现等待现象跑sqltxplain.sql后长时间没反应查v$session发现会话在等enq: TX - row lock contention或library cache lock。原因SQLT 生成报告时会查大量数据字典和动态性能视图如果数据库负载高或者有 DDL 正在执行SQLT 的查询会被阻塞。解决先在测试库生成报告或者选业务低峰期。如果必须在生产库跑用methodSQLT而不是XECUTE避免实际执行 SQL。查v$session确认阻塞源select blocking_session, event from v$session where sid你的SID;如果是 DDL 阻塞等 DDL 完成再跑。4.5 坑五报告 zip 包太大上传 SR 时超时现象生成的报告 zip 包几百 MB上传原厂 SR 系统时超时或失败。原因SQLT 默认收集所有信息包括大量对象元数据和历史统计导致 zip 包膨胀。解决用sqlt/utl下的压缩脚本先压缩或者生成报告时加collection_level1参数只收集核心信息。如果还是太大用split命令分卷压缩split -b 50M report.zip report_part_然后分卷上传。5. 进阶用法用 SQLT 对比不同版本执行计划与自定义收集5.1 跨版本执行计划对比10g 和 19c 跑同一条 SQLSQLT 有一个不太常用但很有价值的功能把不同版本数据库上生成的报告放在一起对比。比如你有一条 SQL 在 10g 上跑 2 秒在 19c 上跑 20 秒想搞清楚执行计划哪里变了。做法是在两个库上分别生成 SQLT 报告然后用sqlt/utl下的对比脚本或者手动对比两个报告里的执行计划部分。-- 在 10g 上生成报告 sqlt/run/sqltxplain.sql sql_idabc123xyz methodXECUTE -- 在 19c 上生成报告 sqlt/run/sqltxplain.sql sql_idabc123xyz methodXECUTE -- 对比两个报告的执行计划 -- 从 10g 报告里提取执行计划 select plan_table_output from table(dbms_xplan.display_sqlset(SQLT$_SQLSET,abc123xyz)); -- 从 19c 报告里提取执行计划 select plan_table_output from table(dbms_xplan.display_sqlset(SQLT$_SQLSET,abc123xyz));逻辑说明两个库上生成的报告执行计划部分可以直接对比。重点看几个地方访问路径全表扫描 vs 索引扫描、连接方式Nested Loop vs Hash Join、并行度是否启用了并行执行。10g 和 19c 的优化器行为差异很大19c 的 Adaptive Execution Plan 可能会在运行时改变执行计划而 10g 没有这个特性。参数说明如果 SQL 在两个库上的 SQL_ID 不一样用sql_text方式生成报告确保分析的是同一条 SQL。对比时注意两个库的统计信息收集时间统计信息差异也会导致执行计划不同。5.2 自定义收集级别只拿你需要的部分SQLT 默认收集所有信息但有时候你只关心执行计划不想等十几分钟收集统计信息和对象元数据。这时候可以用collection_level参数控制收集范围。常见做法是第一次用默认级别生成完整报告后续排查用collection_level1只收集核心信息速度快很多。收集级别包含内容适用场景耗时1执行计划、SQL 文本、基本统计快速排查执行计划问题1-3 分钟2级别 1 对象元数据、系统参数需要看对象结构和参数3-8 分钟3级别 2 运行时统计、等待事件完整诊断8-20 分钟4级别 3 历史 AWR 数据对比历史性能20 分钟以上-- 只收集执行计划和基本统计 sqlt/run/sqltxplain.sql sql_idabc123xyz methodSQLT collection_level1 -- 完整收集 sqlt/run/sqltxplain.sql sql_idabc123xyz methodXECUTE collection_level3逻辑说明collection_level越低收集的信息越少生成报告越快。级别 1 适合快速确认执行计划有没有变级别 3 适合提交 SR 前做完整诊断。级别 4 会从 AWR 取历史数据适合 SQL 已经不在共享池的情况。参数说明method和collection_level可以组合使用。methodSQLT不实际执行 SQLmethodXECUTE会实际执行并收集运行时统计。如果 SQL 有副作用比如 DML不要用XECUTE。5.3 一个我常用的技巧把 SQLT 报告当基线存起来我有个习惯每次数据库升级、迁移、或者大版本变更前对核心 SQL 生成一份 SQLT 报告存到独立的基线目录里。比如/u01/sqlt_baseline/19c_upgrade_before/。升级后再生成一份存到/u01/sqlt_baseline/19c_upgrade_after/。这样一旦升级后性能变差直接对比两份报告的执行计划部分几分钟就能定位到差异点。这个习惯帮我省过好几次通宵排查的时间——有一次 11g 升 19c 后一条核心 SQL 从 3 秒变 30 秒对比报告发现是 19c 的优化器自动启用了并行执行而 11g 没有。手动加了个/* NO_PARALLEL */提示就恢复了。SQLT 报告不是万能的但它给你的是一份可回溯的证据比凭记忆猜靠谱得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表