管好统计信息,开启SQL优化之门

简介:

遇到执行效率低下的SQL语句,对于DBA而言无疑是家常便饭了,但如何快速优化,把它变成小菜一碟,则得看看咱们DBA+社群联合发起人卢飞的经验之谈了。

 

专家简介

  

20160628051305956.jpg

卢飞

DBA+社群联合发起人

 

Oracle 10g OCP,6年Oracle数据库维护经验,对Oracle数据库管理、数据迁移,性能优化有着丰富的实战经验。目前专注于数据库技术及自动化运维方面的研究。

 

在DBA的工作中,SQL优化的工作量占工作很大的一块,我们在平时工作中也是这样,常常遇到一些执行效率低下的SQL语句,而这些执行效率低下的SQL,有的是业务系统刚刚上线的,有的是已经执行很久但因为执行环境变化而导致出现的。这里给大家分享一个SQL的优化案例分析。

 

根据我们监控系统,发现线上OLTP的一个核心业务数据库中有一条SQL执行效率较慢。慢到什么程度?半小时执行278次,平均每次28秒,占用整个DB资源的56%。OLTP系统中,实在太慢了。

 

这里是SQL执行的相关信息。

 

20160628051316564.jpg

 

20160628051323143.jpg

 

SQL优化中,有很多人总是第一要看的就是执行计划,那么我们就看看这条SQL的执行计划。下面可以看到单次执行3秒左右,成本为2,consistent gets较高,执行计划中也是走INDEX RANGE SCAN。

 

20160628051707113.jpg

 

其实单看上面的执行计划Cost还是比较低的,SQL优化中,有很多人总是第一要看的就是执行计划,但是看执行计划一定要结合结构信息,这里的结构信息就是表,索引等结构信息及数据分布信息。

 

我们先看SQL语句吧。以下SQL语句很简单,且在cn字段,c_date字段上都建有索引。

 

20160628051718776.jpg

 

表数据量约有3.6亿数据。

 

20160628051729208.jpg

 

在以上执行计划的基础上,根据对业务的理解,我的疑问是为什么不走cn索引?

 

这里其实可以根据谓词条件,各自查询 一下就能看到结果,根据cn查询到3条,而c_date条件查询出76w。走cn索引才对。

 

20160628051749606.jpg

 

这里也可以使用HINT强制走cn索引看一下效果,使用HINT强制走cn索引后执行时间变为毫秒级。

 

20160628051757881.jpg

 

20160628051804819.jpg

 

SQL优化除了了解结构信息(表,索引),统计信息的准确性也很关键。

 

这里发现最后统计信息分析时间是5月份,相差了3个多月,所以统计信息是不正确的。

 

20160628051817425.jpg

 

统计信息不准确的原因?

 

最终发现Oracle在10g版本中默认的GATHER_STATS_JOB没有启动,这里启动默认的GATHER_STATS_JOB,并单独收集一下表的统计信息。

 

20160628051832140.jpg

 

20160628051841228.jpg

 

收集完统计信息,这条SQL的执行时间下降到毫秒级别,执行计划已经变为IDX_REC_LOG_CN索引的RANGE SACN,consistent gets从原来的19409  降低到了7。效果还是很明显。

 

20160628051850188.jpg

20160628051858294.jpg

同样的SQL又慢了,现在的执行计划, 又开始走IDX_C_LOG_DATE索引了,而且执行时间又回到了2秒, consistent gets变为10404。以下为执行计划:

 

20160628051907389.jpg

 

同样我们还是先检查统计信息是否正确,这里可以看到了统计信息又不正确了,但是我们发现GATHER_STATS_JOB每天都能执行成功。这是为什么?

 

20160628051915616.jpg

 

20160628051922854.jpg

20160628051930472.jpg

20160628051937941.jpg

20160628051948606.jpg

20160628051955833.jpg

解决方法就是定义一个单表收集的JOB。

 

这也是为什么大表都单独定义收集统计信息的原因,面试过很多的同学,基本上说出直接原因的没有多少,都说是照着网上这么做的。

 

20160628052004310.jpg

 

20160628052021166.jpg

这里也可以看到相关的10053事件中的成本信息,具体可以参考以下的地址了解每个类型的含义。

 

20160628052032343.jpg

20160628052041294.jpg
20160628052052719.jpg

最终我们在业务维护时间创建了cn+c_date联合索引后的执行计划,至今再无类似的SQL性能问题。

 

20160628052104345.jpg
20160628052111359.jpg

本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2015-11-27

目录
相关文章
|
19天前
|
SQL 存储 关系型数据库
一文搞懂SQL优化——如何高效添加数据
**SQL优化关键点:** 1. **批量插入**提高效率,一次性建议不超过500条。 2. **手动事务**减少开销,多条插入语句用一个事务。 3. **主键顺序插入**避免页分裂,提升性能。 4. **使用`LOAD DATA INFILE`**大批量导入快速。 5. **避免主键乱序**,减少不必要的磁盘操作。 6. **选择合适主键类型**,避免UUID或长主键导致的性能问题。 7. **避免主键修改**,保持索引稳定。 这些技巧能优化数据库操作,提升系统性能。
214 4
一文搞懂SQL优化——如何高效添加数据
|
1月前
|
SQL 存储 数据库连接
日活3kw下,如何应对实际业务场景中SQL过慢的优化挑战?
在面试中,SQL调优是一个常见的问题,通过这个问题可以考察应聘者对于提升SQL性能的理解和掌握程度。通常来说,SQL调优需要按照以下步骤展开。
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL 数据库】7、SQL 优化
【MySQL 数据库】7、SQL 优化
48 0
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
159 0
|
17天前
|
SQL 关系型数据库 MySQL
mysql一条sql查询出多个统计结果
mysql一条sql查询出多个统计结果
13 0
|
1月前
|
SQL
现有用户成就统计需求,每个用户有多个成就,某一个成就会被多人拥有,写出数据表设计方案,用一条sql查出每个成就(B.ach_name)下的男生(sex=0)和女生(sex=1)分别有多少?
现有用户成就统计需求,每个用户有多个成就,某一个成就会被多人拥有,写出数据表设计方案,用一条sql查出每个成就(B.ach_name)下的男生(sex=0)和女生(sex=1)分别有多少?
41 0
|
20天前
|
SQL 关系型数据库 MySQL
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
36 1
|
21天前
|
SQL 索引
SQL怎么优化
SQL怎么优化
26 2
|
30天前
|
SQL 监控 测试技术
SQL语法优化与最佳实践
【2月更文挑战第28天】本章将深入探讨SQL语法优化的重要性以及具体的优化策略和最佳实践。通过掌握和理解这些优化技巧,读者将能够编写出更高效、更稳定的SQL查询,提升数据库性能,降低系统资源消耗。
|
1月前
|
SQL 关系型数据库 MySQL
[MySQL]SQL优化之sql语句优化
[MySQL]SQL优化之sql语句优化