SQL调优之收集统计信息,重建索引 .

简介:
老外发来邮件,叫Mark做SQL调优。Mark是波兰资深的DBA,是波兰DBA leader。由于是晚上8点半发来的邮件。那么老外肯定认为我休息了。所以把我放在了CC list里面。
我有个习惯,就是晚上不开OC,但是邮件打开,如果是紧急的邮件,就会马上处理,不紧急就放到明天去做。谁叫我有5个项目
忙得不可开交呢,如果紧急问题不马上处理,那么我第二天肯定无法完成其余工作。
 
-----------------------邮件内容-------------------------------------
Hi Mark,
Please help in tuning of below sql – it is executed in ~3 minutes – and should be opened in 5-10 seconds
 
Explain plan looks pretty good (cost 90), maybe some index is needed. We cannot change below sql-code – it is generated by BO.
What we can change are all views which are used by this sql + we can add indexes to tables.
 
Issue is for 99% in view INTRC_RPT_T_INBR_VW or in  INTRC_RPT_INBR_VW
 
Oracle: xxxx  --我改了
User:     xxxx --我改了
Pass:     xxxx --我改了
 
 
SELECT
 INTRC_INITV_DIM.INITV_NAME || ' ' || INTRC_INITV_DIM.INITV_ID || ' ' || INTRC_PROD_DIM.BRAND_SEG_NAME || ' - Power SKU: ' || INTRC_PROD_DIM.BRAND_SEG_PWR_SKU_NAME || ' - ' || INTRC_PROD_DIM.BRAND_SEG_PWR_SKU_ID ,
 INTRC_PROD_DIM.BRAND_NAME,
 INTRC_RPT_T_INBR_VW.HDR_ORDR,
 INTRC_RPT_T_INBR_VW.MEASR_ORDR,
 INTRC_RPT_T_INBR_VW.M00,
 INTRC_RPT_T_INBR_VW.M01,
 INTRC_RPT_T_INBR_VW.M02,
 INTRC_RPT_T_INBR_VW.M03,
 INTRC_RPT_T_INBR_VW.M04,
 INTRC_RPT_T_INBR_VW.M05,
 INTRC_RPT_T_INBR_VW.M06,
 INTRC_RPT_T_INBR_VW.M07,
 INTRC_RPT_T_INBR_VW.M08,
 INTRC_RPT_T_INBR_VW.M09,
 INTRC_RPT_T_INBR_VW.M10,
 INTRC_RPT_T_INBR_VW.M11,
 INTRC_RPT_T_INBR_VW.M12,
 INTRC_RPT_T_INBR_VW.INITV_COPY,
 INTRC_INITV_DIM.INITV_NAME || ' ' || INTRC_INITV_DIM.MKT_NAME || ' ' || INTRC_INITV_DIM.INITV_ID,
 INTRC_RPT_DESC_PRC.HDR_NAME,
 INTRC_RPT_DESC_PRC.MEASR_NAME,
 INTRC_RPT_DESC_PRC.MEASR_DESC,
 INTRC_RPT_DESC_PRC.MEASR_PRCSN,
 INTRC_RPT_DESC_PRC.MEASR_TYPE
FROM
 INTRC_INITV_DIM,
 INTRC_PROD_DIM,
 INTRC_RPT_T_INBR_VW,
 INTRC_RPT_DESC_PRC,
 INTRC_INITV_SEL_VW
WHERE
 ( INTRC_INITV_SEL_VW.INITV_SKID=INTRC_INITV_DIM.INITV_SKID )
 AND ( INTRC_RPT_T_INBR_VW.INITV_SKID=INTRC_INITV_SEL_VW.INITV_SKID and INTRC_RPT_T_INBR_VW.SID=INTRC_INITV_SEL_VW.SID )
 AND ( INTRC_RPT_T_INBR_VW.COL_NAME=INTRC_RPT_DESC_PRC.COL_NAME and INTRC_RPT_T_INBR_VW.TIME_PERD_LVL=INTRC_RPT_DESC_PRC.TIME_PERD_LVL )
 AND ( INTRC_PROD_DIM.PROD_SKID=INTRC_RPT_T_INBR_VW.PROD_SKID )
 AND 
 (
   ( INTRC_INITV_SEL_VW.SID IN ('1282123246366_51775798') )
   AND
   ( INTRC_RPT_T_INBR_VW.RPT_NAME in ('3BRNN_MI') )
 );
---------------------邮件内容---------------------------
 
老外的这些话引起了我的注意:

 

Please help in tuning of below sql – it is executed in ~3 minutes – and should be opened in 5-10 seconds
 请帮我调整一下SQL,现在执行了3分钟,但是应该在5-10秒完成。
Explain plan looks pretty good (cost 90), maybe some index is needed. We cannot change below sql-code – it is generated by BO.
执行计划看起来想当好(成本只有90),可能是需要添加某些索引,我们不能更改下面的SQL代码,因为他是BO(SAP)自动生成的。
What we can change are all views which are used by this sql + we can add indexes to tables.
我们能做的就是更改视图,或者在表上面添加索引。

 

Issue is for 99% in view INTRC_RPT_T_INBR_VW or in  INTRC_RPT_INBR_VW
 
问题的99%的可能性是出在 这2个视图上面 INTRC_RPT_T_INBR_VW 或者in INTRC_RPT_INBR_VW

 

 

 
发邮件的是BO tech leader,他说这个SQL应该在5-10秒以内完成,那么隐含的意思就是以前这个SQL是能够在10秒以内完成的,同时他也希望我们能让这个SQL在10秒以内跑完。

 

根据老外的阐述,我认为,由于某种原因,执行计划发生了改变,导致SQL以前能在10秒以内完成,现在却要花3分钟。那么导致执行计划的改变的原因通常是由于统计信息过期导致的。
于是执行下面操作:
exec dbms_stats.flush_database_monitoring_info;
select owner || '.' || table_name name , object_type,stale_stats,last_analyzed
from dba_tab_statistics where owner like 'ADWGQ%' AND table_name in
(
'INTRC_INBR_FCT',
'INTRC_RPT_LYOUT_PRC',
'INTRC_INPR_BRDG_DIM',
'INTRC_INITV_DIM',
'INTRC_INPR_BRDG_DIM',
'INTRC_USER_SELCT_PRC',
'INTRC_PROD_DIM',
'INTRC_INITV_TIME_BRDG_DIM',
'INTRC_RPT_DESC_PRC'
);
 结果就不贴出了---因为用的TOAD工具,而且调优完成后电脑卡死了,奶奶的大悲剧。
发现果然有2个表统计信息过期了,如何查看统计信息过期?请看stale_stats字段,如果为YES,表示统计信息过期了。而这里,确实有2个表统计信息过期了。我使用了如下脚本收集统计信息。
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'ADWGQ_INTRC',
tabname => 'INTRC_RPT_DESC_PRC',
estimate_percent => 50,  
method_opt => 'for all columns size repeat',
degree => DBMS_STATS.AUTO_DEGREE,
cascade=>TRUE
);
END;
/
 
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'ADWGQ_INTRC',
tabname => 'INTRC_INBR_FCT',
estimate_percent => 50,
method_opt => 'for all columns size repeat',
degree => DBMS_STATS.AUTO_DEGREE,
granularity => 'ALL',
cascade=>TRUE
);
END;
/
除了对上面2个过期的表收集统计信息外,我还另外对其他表重新收集了统计信息,因为这些表并不大,最大的才几十万条数据,而我这里是4节点,8CPU,HPUX 环境,收集统计信息是非常快的。
事实上也非常快,基本上10秒以内搞定。
收集统计信息之后,跑了一下SQL,16秒搞定
------老外又回复邮件,感谢-----

 

Great J it is much much better J
 
Thank you very much
------邮件回复内容-------------
然而到这里,优化并没完成,老外的要求应该是10秒以内出结果。那怎么办呢?
根据执行计划,我发现该执行计划使用了10个索引。于是我又rebuild了这10个索引
那么这次8秒钟就出结果了,好了终于完成了老外的优化请求。
总结:这次SQL调优,其实很简单,再简单不过了?不是吗。不过也有值得我们学习的地方。
首先,你需要根据他人提供的信息,快速定位问题的根源。比如这里我就根据老外说应该(should be)

 

5-10秒以内完成,那么我就有80%以上的把握肯定统计信息出问题了。
其次就是,即使老外不提应该在5-10秒内完成,我也会去检查统计信息的时效性。
下面列出我做SQL调优的步骤:
一:仔细观察该SQL语句,分析表结构,表大小,行数。
二:分析统计信息的时效性,段高水位,如果统计信息失效,那么收集统计信息,然后继续下面步骤。
三:查看连接列基数,选择性,where条件列基数,选择性,直方图信息。
四:查看表上面有哪些索引,哪些类型的索引,分别在那些列上面。
五:分析现有索引的选择性,聚簇因子等信息。
六:查看表,索引的degree,instance 因为这可能导致并行。
另外得到的一个经验就是:定期rebuild index吧,肯定是有好处的
这里rebuild index之后从16秒提高到8秒,性能整整提升了1倍。




本文转自 vfast_chenxy 51CTO博客,原文链接:http://blog.51cto.com/chenxy/741848,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
200 2
|
29天前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
36 8
|
1月前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
1月前
|
SQL
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
35 1
|
2月前
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
|
3月前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
644 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
2月前
|
SQL 关系型数据库 MySQL
如何确认SQL用了索引:详细技巧与方法
在数据库管理中,索引是提高SQL查询性能的重要手段
|
2月前
|
SQL Oracle 关系型数据库
Oracle SQL:了解执行计划和性能调优
Oracle SQL:了解执行计划和性能调优
76 1
|
3月前
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
|
3月前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
40 1