SQL瓶颈分析,以及适应最佳执行计划的探讨
原文地址: https://blog.csdn.net/daiqiulong2/article/details/86546446?tdsourcetag=s_pcqq_aiomsg
年纪大了,慢慢的写技术文档也不皮了。一五一十的说说清楚, 问题是什么, 解决方案又是什么。 中规中矩的写。
SQL_ID: 1m6akd1s2144u, 执行成本: 40万次/h 3000逻辑读/次。
TOP10SQL的问题类似, 现在分析优化d4wcdsskp0f47
d4wcdsskp0f47 SQL和这个SQL类似。
SELECT * FROM (SELECT XX.*, ROWNUM AS RN FROM (select count(*) from CUST_YC_APP.PARTY_CERT P inner join CUST_YC_APP.CUSTOMER C on P.PARTY_ID = C.PARTY_ID and C.STATUS_CD = '1100' where P.PARTY_ID in (:1 ) and P.STATUS_CD in (:2 ) and P.IS_DEFAULT = '1') XX WHERE ROWNUM <= 1000 ) XXX WHERE RN > 0
执行计划:
执行计划中有笛卡尔积, 但是问题并不在笛卡尔积中。(好多DBA看到笛卡尔集就说笛卡尔集有性能问题,其实是不严谨的,的确很多笛卡尔集是有性能问题,但是此处不是最主要的问题)
查询中绑定变量的值如:B1:15151722241919 B2: ‘1000’
带入到SQL中查询 只9逻辑读。
查询性能瓶颈:
通过采样分析,更多的性能消耗在执行计划的第9步。也就在C表(CUSTOMER)的回表上。
SQL中得出C表用到两个字段 C.PARTY_ID,C.STATUS_CD。 PARTY_ID上建有索引,回表就是为了访问STATUS_CD字段。
因此建议建立索引index C ( PARTY_ID, STATUS_CD ); 这样可以避免回表。
针对该SQL 优化建议建立索引,即可。
猜测根本原因:
是否是部分由于C表 PARTY_ID某些特定值过多,造成大量会表。
查询表中的数据分布以及绑定变量中的值。
查询数据分布:C表 PARTY_ID字段的选择性 98%,但是有个值,重复率非常高。
查询数据分布以及关联绑定变量。
(这个SQL只表示这些值在绑定变量中出现过, 但是出现的频率未知。。。。但能说明问题)
这个SQL表明,部分不均匀的
果然当PARTY_ID = 15151723602037, 回表需要 回10万次。
用auto trace 中单次执行需要消耗逻辑读7770。 针对该问题已经有相关建议。
下文是探讨 针对该表数据分布以及SQL 如何进一步优化。
既然数据分布不均衡,是否可以通过收集直方图来改善性能? 答案是否定的。
建立测试表: CUSTOMER_test
create table CUSTOMER_test tablespace TBS_CUST_DATA as
select * from CUST_YC_APP.CUSTOMER C ;
create index idx_pid on CUSTOMER_test(PARTY_ID);
收集直方图:
begin
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'CHECKDB',
TABNAME => 'CUSTOMER_TEST',
ESTIMATE_PERCENT => 50,
METHOD_OPT => 'for columns PARTY_ID size skewonly',
DEGREE => 2,
GRANULARITY => 'ALL',
CASCADE => TRUE);
END;
执行SQL:SQL效率更差。 15万逻辑读/次
回到SQl中。关键部分:
需要确认是否可以改成半连接, ( 业务那边是要确认是否可以等价改写,此处讨论这种数据分布情况下如何实施优化 )
因为针对数据分布不均衡半连接效果比较好。
改写SQL:
SELECT *
FROM (SELECT XX.*, ROWNUM AS RN
FROM (select count(1)
from CUST_YC_APP.PARTY_CERT P
where P.PARTY_ID in (15151723602037)
and P.PARTY_ID in ( select /*+ nl_sj index(c) */ C.PARTY_ID from checkdb.CUSTOMER_test C where C.STATUS_CD = '1100' )
and P.STATUS_CD in ('1000')
and P.IS_DEFAULT = '1') XX
WHERE ROWNUM <= 1000) XXX
WHERE RN > 0;
9 逻辑读/次. (不添加hints 就会走全表,成本1286次/S )
不添加hints 就会走全表,成本1286次/S
SQL无法自动走用好的执行计划, 需要绑定hints才走。 如何自动走好的执行计划??
答案
1 删除直方图。
2设置数据选择性, 综合比较选择性设置成 30% 比较好。
(选择性设置成30, 只要数据总量 * 30% 即可)
删除直方图, 设置选择性。
begin
dbms_stats.delete_column_stats(OWNNAME => 'CHECKDB',
TABNAME => 'CUSTOMER_TEST',
colname =>'PARTY_ID',
col_stat_type=>'HISTOGRAM' );
end;
begin
DBMS_STATS.set_column_stats(OWNNAME => 'CHECKDB',
TABNAME => 'CUSTOMER_TEST',
colname =>'PARTY_ID',distcnt => 1645919);
end;
这次测试不添加hints的情况下, 是否能走最好的执行计划。
果然走nested_loop 半连接 并且走 C(PARTY_ID) 索引 (图就不贴了)。9逻辑读
另外也测试了SQL
select count(1)
from CHECKDB.CUSTOMER_TEST t
where PARTY_ID = 15151723602037 and t.status_cd in ('1100');
收集直方图: 走全表扫描 156935逻辑读/次
删除直方图: 走索引扫描 7903逻辑读/次
至于什么情况下收集直方图,删除直方图,收集统计信息。 这个不多说了。 看我之前博客设置统计信息优化SQL的案例。
---------------------
作者:越烟
来源:CSDN
原文:https://blog.csdn.net/daiqiulong2/article/details/86546446
版权声明:本文为博主原创文章,转载请附上博文链接!
SQL瓶颈分析,以及适应最佳执行计划的探讨的更多相关文章
- 浅析SqlServer简单参数化模式下对sql语句自动参数化处理以及执行计划重用
我们知道,SqlServer执行sql语句的时候,有一步是对sql进行编译以生成执行计划, 在生成执行计划之前会去缓存中查找执行计划 如果执行计划缓存中有对应的执行计划缓存,那么SqlServer就会 ...
- SQL Server INSET/UPDATE/DELETE的执行计划
DML操作符包括增删改查等操作方式. insert into Person.Address (AddressLine1, AddressLine2, City, StateProvinceID, Po ...
- SQL Server 性能调优 之执行计划(Execution Plan)调优
SQL Server 存在三种 Join 策略:Hash Join,Merge Join,Nested Loop Join. Hash Join:用来处理没有排过序/没有索引的数据,它在内存中把 Jo ...
- SQL Server如何查看存储过程的执行计划
有时候,我们需要查看存储过程的执行计划,那么我们有什么方式获取存储过程的历史执行计划或当前的执行计划呢? 下面总结一下获取存储过程的执行计划的方法. 1:我们可以通过下面脚本查看存储过程的执行计划,但 ...
- 不会看 Explain执行计划,劝你简历别写熟悉 SQL优化
昨天中午在食堂,和部门的技术大牛们坐在一桌吃饭,作为一个卑微技术渣仔默默的吃着饭,听大佬们高谈阔论,研究各种高端技术,我TM也想说话可实在插不上嘴. 聊着聊着突然说到他上午面试了一个工作6年的程序员, ...
- 使用Oracle执行计划分析SQL性能
执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述.即就是对一个查询任务,做出一份怎样去完成任务的详细方案. 如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的 ...
- SQL Server 执行计划分析
当一个查询到达数据库引擎时,SQL Server执行两个主要的步骤来产生期望的查询结果: 第一步:查询编译,生成查询计划. 第二步:执行这个查询计划. 1. 用于演示分析执行计划的查询语句 /* 查询 ...
- SELECT TOP 1 比不加TOP 1 慢的原因分析以及SELECT TOP 1语句执行计划预估原理
本文出处:http://www.cnblogs.com/wy123/p/6082338.html 现实中遇到过到这么一种情况: 在某些特殊场景下:进行查询的时候,加了TOP 1比不加TOP 1要慢(而 ...
- SQL Server 执行计划缓存
标签:SQL SERVER/MSSQL SERVER/数据库/DBA/内存池/缓冲区 概述 了解执行计划对数据库性能分析很重要,其中涉及到了语句性能分析与存储,这也是写这篇文章的目的,在了解执行计划之 ...
随机推荐
- Springboot 拦截器的背后
今天写了个拦截器对一些mapping做了些处理,写完之后突然很想看看拦截器是怎么加进spring里面.对着源码debug了一遍.又有了新的收获. 1.拦截器的实现 1.实现HandlerInterce ...
- LocalDateTime反序列化,LocalDateTime格式化
使用mybatis-plus的时候出现了LocalDateTime类(jdk8 中新出现的类 那么我在反序列化的时候出了问题. 我在springboot 2.1.3 中使用以下类结局问题) 用到了下面 ...
- Asp.Net SignalR Hub集线器
集线器Hub类 使用持久连接类去开发是有些困难的,因为基于事件的开发方式,我们可以进行操作的地方也仅仅只是OnReceived事件内,这有些像websocket的方式.我们迫切的需要一种更人性化,更为 ...
- JDK源码分析(6)之 LinkedHashMap 相关
LinkedHashMap实质是HashMap+LinkedList,提供了顺序访问的功能:所以在看这篇博客之前最好先看一下我之前的两篇博客,HashMap 相关 和 LinkedList 相关: 一 ...
- 【Java并发编程】Callable、Future和FutureTask的实现
启动线程执行任务,如果需要在任务执行完毕之后得到任务执行结果,可以使用从Java 1.5开始提供的Callable和Future 下面就分析一下Callable.Future以及FutureTask的 ...
- Thread之九:stop
搞过Java线程的人都知道,stop这个方法是臭名昭著了,早就被弃用了,但是现在任然有很多钟情与他的人,永远都放不下他,因为从他的字面意思上我们可以知道他貌似可以停止一个线程,这个需求是每个搞线程开发 ...
- [二] JavaIO之File详解 以及FileSystem WinNTFileSystem简介
File类 文件和目录路径名的抽象表示形式. 我们知道,对于不同的操作系统,文件路径的描述是不同的 比如 windows平台:用\ linux平台:用/ File是Java为了这一概念提供的抽象描 ...
- .Net语言 APP开发平台——Smobiler学习日志:SmoOne新增考勤功能
大家好!SmoOne这次新增了考勤功能,大家打开SmoOne应用便可体验,无需重新下载更新.如果没有下载SmoOne客户端,可以在apps.smobiler.com进行下载安装. 另外,SmoOne开 ...
- Log4Net使用学习笔记
项目源文件下载https://files.cnblogs.com/files/ckym/Log4NetTestSourceCode.zip Log4net是一款非常好用的日志记录的框架,使用它可以实现 ...
- js三部曲---预编译
函数内:1,创建AO对象//Activation Object 2,找函数内形参和变量声明,将其作为AO对象的属性名,值为undefined. 3,实参赋到AO对象 形参名里 4,在函数体里找函数声明 ...