如何诊断sql数据?(代码片段)

风风风啊 风风风啊     2022-11-30     711

关键词:

当一个SQL出现性能问题时,可以使用SQL_TRACE 或者 10046事件来跟踪SQL,通过生成的trace来了解SQL的执行过程。我们在查看一条SQL的执行计划的时候,只能看到CBO 最终告诉我们的执行计划结果,但是不知道CBO 是根据什么来做的。如果遇到了执行计划异常,可以借助Oracle 10053事件进行跟踪。10053事件是oracle提供的用于跟踪sql语句成本计算的内部事件,它能记载CBO模式下oracle优化器如何计算sql成本,生成相应的执行计划。

通过session级别跟踪:

ALTER SESSION SET EVENTS=\'10053 trace name context forever, level 1\';

或ALTER SESSION SET EVENTS=\'10053 trace name context forever, level 2\';

执行相关sql

explain plan for select count(*) from obj$;

ALTER SESSION SET EVENTS \'10053 trace name context off\';

对特定session启用跟踪:

通过调用 DBMS_SYSTEM. SET_EV包实现

PROCEDURE SET_EV

Argument Name Type In/Out Default?

------------------------------ ----------------------- ------ --------

SI BINARY_INTEGER IN

SE BINARY_INTEGER IN

EV BINARY_INTEGER IN

LE BINARY_INTEGER IN

NM VARCHAR2 IN

查询v$sessiowww.pizei.comn 视图获取进程信息

SQL> select sid,serial#,username from v$session where username is not null;

SID SERIAL# USERNAME


125 25 SYS

执行跟踪

exec dbms_system.SET_EV(125,25,10053,1,\'\');

结束跟踪

exec dbms_system.SET_EV(125,25,10053,0,\'\');

查询系统对应session trace文件

select value from v$diag_info where name = \'Default Trace File\';

经过开发人员确认该sql在测试库(LINUX+ 12.2.0.1 单机环境)执行只需要几秒即可(数据量相差不大)完成,其中bs_loan_card_addition、bs_loan_card、bs_loan_contract_addition三张表的数据量都在200万行左右。

获取到生产环境该sql执行计划如下:

测试环境该sql执行计划如下:

首先怀疑统计信息不准确导致CBO在页游访问BS_LOAN_CARD表的时候选择错误,本应该选择BS_LOAN_CARD_I3索引(因为CUSTOMER_NO"=\'1000193229’的选择性很好)而这也是开发设计这个索引的原因。但结果是选择了BS_LOAN_CARD_I0索引(对应的是BS_LOAN_CARD.LOAN_CARD_NO,该列唯一的),而过滤条件根本没有这个列,他只是作为关联条件与bs_loan_card_addition表进行连接。

因此首先检查统计信息,意外发现BS_LOAN_CARD.LOAN_CARD_NO,列上居然存在一个HYBIRD类型的直方图,理论上来说该值的唯一性非常好,不应该收集直方图,因此直接删除了该列上的直方图,再次检查发现执行计划仍未改变。

尝试使用10053对该SQL执行计划的产生过程进行跟踪,发现如下信息:

而且结合执行计划

这个执行计划简单理解来说就是首先对BS_LOAN_CARD_ADDITION进行全表扫描,然后在这个所得的结果集里面每一行的LOAN_CARD_NO列拿出来到BS_LOAN_CARD里面匹配,这就是第6部里面出现了一个"B"."LOAN_CARD_NO"=:B1原因,而这个就是oracle改写后的结果。而从其选择对BS_LOAN_CARD_ADDITION进行全表扫描就不可避免的导致了效率会很低。而且其后的rows 估算为2444K,这个是贴合实际的,所以之前的删除直方图不会有结果。而测试上的改写结果明显跟这个不一样,排除统计信息的影响,那么就开始怀疑cbo内部的算法选择问题,再结合那个可疑 的 “CBQT bypassed forquery block UPD$1 (#0): Disabled by parameter. ”提示,怀疑优化器参数在两个环境中有区别,

一:_optimizer_cost_based_transformation设为linear(默认值),其有如下值:

"exhaustive", "iterative","linear", "on", "off"。

本例中该参数就是默认值,该参数可控制是否允许CBO进行改写

二:_optimizer_squ_bottomup 参数值为true(默认值).

而生产环境中恰好相反为false,所以生产的trace中会有Disabled by parameter 字眼

_optimizer_squ_bottomup enables unnesting of subquery in a bottom-upmanner;

该参数默认为true,即开启子查询自底向上的展开功能(也就是类似unnest hint的功能),unnest称之为对子查询展开,顾名思义,就是不让子查询孤单地嵌套(nest)在里面。

sql工具sql调优和诊断神器sqltxplain(sqlt)简介(代码片段)

SQLTSQLTXPLAIN(SQLT)是Oracle专家开发的,用于诊断SQL相关的问题的工具,简单易用却功能强大。SQLT会用户根据指定的模式,连接到数据库,收集执行计划、基于成本的OptimizerCBO统计信息、Schema对象元数据、性能统计信... 查看详情

sql上下文诊断(代码片段)

查看详情

诊断和响应故障_使用数据恢复顾问(datarecoveryadvisor)诊断和修复故障(代码片段)

本章阐述如何使用RMAN中的数据恢复顾问(DataRecoveryAdvisor)工具来诊断和修复数据库故障。1.数据恢复顾问概述1.1.数据恢复顾问目的数据恢复顾问是一个可以自动诊断数据故障,确认和提出合适的修复选项... 查看详情

mysqlshowprofiles性能跟踪诊断工具(代码片段)

前言Showprofiles最大的好处是可以查看执行sql语句时各个环节的执行时间,Showprofiles是5.0.37之后添加的,要想使用此功能,要确保版本在5.0.37之后。可以执行sqlselectversion();查看当前数据库版本。开启profiling启动数据库... 查看详情

sql调优和诊断神器sqltxplain(sqlt)简介(二xploremodule)(代码片段)

XPLOREModule注意点执行例XPLOREModule对于SQL的很多Optimzer问题如执行计划异常、SQL慢、结果不正(WrongResult)等,如果在测试环境可以重现的话,可以通过SQLT的xplore功能,调整各种参数和Optimzer的FixControl来找到回避... 查看详情

如何看懂uds诊断报文(代码片段)

UDS介绍UDS(UnifiedDiagnosticServices,统一的诊断服务)诊断协议是ISO15765和ISO14229定义的一种汽车通用诊断协议,位于OSI模型中的应用层,它可在不同的汽车总线(例如CAN,LIN,Flexray,Ethernet和K-line)上实现。UD... 查看详情

如何看懂uds诊断报文(代码片段)

UDS介绍UDS(UnifiedDiagnosticServices,统一的诊断服务)诊断协议是ISO15765和ISO14229定义的一种汽车通用诊断协议,位于OSI模型中的应用层,它可在不同的汽车总线(例如CAN,LIN,Flexray,Ethernet和K-line)上实现。UD... 查看详情

如何看懂uds诊断报文(代码片段)

UDS介绍UDS(UnifiedDiagnosticServices,统一的诊断服务)诊断协议是ISO15765和ISO14229定义的一种汽车通用诊断协议,位于OSI模型中的应用层,它可在不同的汽车总线(例如CAN,LIN,Flexray,Ethernet和K-line)上实现。UD... 查看详情

sql调优指南笔记18:analyzingstatisticsusingoptimizerstatisticsadvisor(代码片段)

...ngOptimizerStatisticsAdvisor”的笔记。OptimizerStatisticsAdvisor分析如何收集优化器统计信息,然后提出建议。18.1AboutOptimizerStatisticsAdvisorOptimizerStatisticsAdvisor是一种内置诊断软件,可分析统计数据和与统计数据相关的任务的质量。... 查看详情

离子原生诊断-如何知道用户何时回到应用程序(代码片段)

在我的Ionic应用程序中,我要求用户通过以下代码启用位置:letalert=this.alertCtrl.create(title:'Posizione',message:'AbilitailGPSperlocalizzarelatuaposizione.',buttons:[text:'No',role:'cancel',handler:()=>,text:'Sì',hand 查看详情

实时即未来,车联网项目之远程诊断实时故障分析(代码片段)

文章目录远程诊断实时故障业务什么是远程诊断实时故障应用场景介绍常用故障分析指标与含义业务中间表数据结构分析结果表数据结构高德地图解决逆地理坐标问题实时故障分析任务远程诊断实时故障分析车型车系销售信息广... 查看详情

实时即未来,车联网项目之远程诊断实时故障分析(代码片段)

文章目录远程诊断实时故障业务什么是远程诊断实时故障应用场景介绍常用故障分析指标与含义业务中间表数据结构分析结果表数据结构高德地图解决逆地理坐标问题实时故障分析任务远程诊断实时故障分析车型车系销售信息广... 查看详情

实时即未来,车联网项目之远程诊断实时故障分析(代码片段)

文章目录远程诊断实时故障业务什么是远程诊断实时故障应用场景介绍常用故障分析指标与含义业务中间表数据结构分析结果表数据结构高德地图解决逆地理坐标问题实时故障分析任务远程诊断实时故障分析车型车系销售信息广... 查看详情

oraclesqlt(sqltxplain)诊断工具(代码片段)

oraclesqlt(sqltxplain)诊断工具原创Oracle作者:selectshen时间:2016-05-3112:37:0878130文档DocID1526574.1包含了下载,安装,参考资料,最佳实践等相关信息.以下是一个简单的安装测试:OS:centos6.6DB:oracle11.2.0.4#安装[oracle@ct6604~]$llsqlt*-rw-r--r--1rootroot919... 查看详情

sql如何在mysql中创建数据库。(代码片段)

查看详情

sql如何在mysql中将数据插入表中(代码片段)

查看详情

sql如何从单个用户中获取数据库(代码片段)

查看详情

expert诊断优化系列------------------冤枉磁盘了(代码片段)

...数据问题基本又是搜遍百度各种方法尝试个遍,可能错过诊断问题的最佳时机又可能尝试一堆方法最后无奈放弃。    怎么样让琐事缠身的程序维护人员,用最快的方式解决数据库出现的问题?怎么让我们程序员的痛苦降低... 查看详情