我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SQL优化之统计信息和索引

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SQL优化之统计信息和索引

大部分情况下的sql优化的场景,都是发生在我们想让我们的sql语句运行的更快一点,这个时候我们往往会采取一些“措施”调整sql的执行路径以便它们能更快的运行结束。

刚入dba行业,常常听到导师和我说的一句话“20%的sql优化技能就能优化80%的sql性能问题”。大部分情况下sql优化并不复杂,而很关键的一步是我们能不能发现问题,然后才能对症下药。今天我们先从sql优化中的统计信息、索引这2个方面来学习了解一下sql。

对于cbo模式,统计信息极为重要,这是影响sql语句执行的一个重要的因素。对于数据变化量大的数据库,会很容易出现统计信息过旧的问题即系统记录的表信息和实际表的信息不一致。那么优化器在选择最优执行路径的时候就可能选择不合适的执行路径(非最优路径)。所以我们一线运维常常需要定期的收集统计信息。那么问题来了,统计信息收集依据呢?

既然要收集,那么很多时候我们可以通过dba_tables视图中的LAST_ANALYZED字段看看上一次的收集日期,做个是否有必要做统计收集的预判断。


sys@RAC>alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';
Session altered.    
sys@RAC>select owner,TABLE_NAME,LAST_ANALYZED from dba_tables where table_name='T1';
OWNER                TABLE_NAME           LAST_ANALYZED
-------------------- -------------------- -------------------
TEST                 T1                   2017-10-28 15:08:25

既然有近一年没有收集过统计信息,那么这类表统计信息不准的嫌疑就会很大。

还有一点就是当我们在看sql执行计划最后有输出dynamic sampling used for thisstatement ,那么说明本次sql执行发生了 动态采样 。动态采样是指在段(表,索引,分区)没有分析的情况下,为了使CBO 优化器得到足够的信息以保证做出正确的执行计划而发明的一种技术,可以把它看做系统自动收集统计信息的一种手段。当对象没有统计信息时(即没有做分析),动态采样技术可以通过直接从需要分析的对象抽样数据块来抽象出CBO需要的统计信息。

动态采样需要额外的消耗数据库资源,所以如果SQL执行频率很高,这部分资源的消耗可能对sql执行效率的影响也会很大,这一点需要我们注意,在这样一个环境中,是不宜使用动态采样的。所以为了防止动态采样带来的系统性能的额外消耗,所以我们建议定期对数据库中的缺失或者过旧的统计信息表做定期的统计信息收集。

在上述两种情况中,我们一般需要收集统计信息。那么,如何收集又是另外一个问题。

示例:


BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'xxxxx',
                            TABNAME => 'SR_PROBLEM_xxxx',
                            PARTNAME=>'P201802',  
                            ESTIMATE_PERCENT => 1,
                            METHOD_OPT => 'FOR ALL COLUMNS SIZE 1',
                            NO_INVALIDATE=> FALSE,
                            FORCE=>TRUE,
                            CASCADE => TRUE,
                            DEGREE  => 10);
END;
/

参数说明:

·  ownname:要分析表的拥有者

·  tabname:要分析的表名

·  partname:分区的名字,只对分区表或分区索引有用

·  estimate_percent:采样行的百分比,取值范围[0.000001,100]

·  method_opt:决定histograms信息是怎样被统计的,method_opt的取值如下(默认值为FOR ALL COLUMNS SIZE AUTO)

·  for columns <list> SIZE <N> |REPEAT | AUTO | SKEWONLY:统计指定列的histograms,N的取值范围[1,254]

·  force:即使表锁住了也收集统计信息

·  cascade:是收集索引的信息,默认为FALSE

·  degree:决定并行度,默认值为null


那么只有上述两种情况需要收集统计信息么?答案显然是否定的。而且统计信息收集的参数丰富,这里也只是示例,够日常场景下使用而已。很多情况下还需要根据实际情况动态调整的。

 

下面我们看看索引,在大多数场景下合理的使用索引会使sql语句的执行会有指数级的性能提升,但是索引虽然好,但是千万不能过度使用,因为维护索引需要消耗一定的资源的。

如果一个数据表中存有海量的数据记录,当对表执行指定条件的查询时,常规的查询方法会将所有的记录都读取出来,然后再把读取的每一条记录与查询条件进行对比,最后返回满足条件的记录。这样进行操作的时间开销和I/O开销都很大。对于这种情况,就可以考虑通过建立索引来减小系统开销。

 

如果要在表中查询指定的记录,在没有索引的情况下,必须遍历整个表,而有了索引之后,只需要在索引中找到符合查询条件的索引字段值,就可以通过保存在索引中的ROWID快速找到表中对应的记录。形象的描述就是类似字典目录的作用,能快速的查询到相关资料。

现在我们常用的索引技术按照索引数据的存储方式可以将索引分为B树索引、位图索引、反向键索引和基于函数的索引等;按照索引列的唯一性可以分为唯一索引和非唯一索引;创建唯一性索引还能保证相关列内的数据的唯一性。按照索引列的个数可以分为单列索引和复合索引。

 

建立和规划一个合理的能提速sql访问效率的索引需注意以下几点:

1. 索引应该建立在WHERE子句频繁引用列表上,如果在大表上频繁使用某列或某几个列作为条件执行索引操作,并且检索行数低于总行数的15%(经验值),那么可以考虑在这些列上建立组合索引。

2. 如果经常需要基于某列或者某几个列排序操作,那么应该在这些列上建立索引可以加快数据排序速度。

3. 限制表的索引个数。索引主要用于加快查询速度,但会降低DML操作的速度。索引越多,DML操作速度越慢,尤其会极大地影响INSERT和DELETE操作的速度。因此,规划索引时,必须仔细权衡查询和DML的需求。

4. 不适合建立索引的列的特点:很少进行搜索的列上;列取值比较少的列上;blob类型的列上等。

5. 在创建过程中,千万不要中断,因为会导致oracle数据字典内已经包含了该索引的信息,但是却实际没有为该索引分配段,导致重新建立索引,并且删除索引报错。


|  作者简介

李誉军,沃趣科技数据库工程师

主要参与公司产品实施、测试、维护以及优化。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SQL优化之统计信息和索引

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SQL Server高级进阶之索引优化

1.1、查找缺失索引SELECT A.USER_SEEKS 查找次数,A.USER_SCANS 扫描次数, ROUND(A.AVG_TOTAL_USER_COST,2) 减少的用户查询的平均成本,A.AVG_USER_IMPACT 可能获得的平均百分比收
SQL Server高级进阶之索引优化
2016-07-26

sql server重建全库索引和更新全库统计信息通用脚本

重建全库索引:exec sp_msforeachtable "DBCC DBREINDEX(""?"")"更新全库统计信息:--更新全部统计信息exec sp_updatestats实例反馈:  在实际项目中,出现过导入数据的存储过程执行需要大概46分钟,而通
2017-09-08

MySql索引原理和SQL优化方式

目录一、索引与约束1、索引是什么2、索引的分类列的属性-索引约束数据结构索引实现-物理存储3、使用索引的场景二、索引方式1、聚集索引2、辅助索引(二级索引)3、覆盖索引4、最左匹配规则5、索引下推三、索引的失效和原则1、索引失效2、索引原则
MySql索引原理和SQL优化方式
2024-09-24

SQL Server高级进阶之索引优化查询

1.1、查找缺失索引SELECT A.USER_SEEKS 查找次数,A.USER_SCANS 扫描次数, ROUND(A.AVG_TOTAL_USER_COST,2) 减少的用户查询的平均成本,A.AVG_USER_IMPACT 可能获得的平均百分比收
SQL Server高级进阶之索引优化查询
2014-08-11

PL/SQL中的索引怎么设计与优化

在 PL/SQL 中,索引的设计和优化是非常重要的,可以提高数据库查询的性能。以下是一些关于索引设计与优化的建议:设计合适的索引:在创建索引时,要根据查询的需求选择合适的字段进行索引。通常会选择经常用于查询的字段、排序或分组的字段以及连接表
PL/SQL中的索引怎么设计与优化
2024-05-08

Swoole和Workerman对PHP与MySQL的索引统计和索引选择的优化方法

引言:在Web开发过程中,数据库是必备的组件之一。而索引是对数据库中数据进行快速查找的关键因素之一。索引的选择和优化可以极大地提高数据库的查询性能。在本文中,我们将介绍如何使用Swoole和Workerman对PHP与MySQL的索引进行统
2023-10-21

索引如何优化Oracle的分组统计

要优化Oracle的分组统计,可以采取以下措施:创建合适的索引:在需要进行分组统计的列上创建合适的索引,可以加快查询速度。可以考虑在分组列上创建单列索引或者联合索引。考虑使用覆盖索引:如果查询语句中只包含需要统计的列和分组列,可以考虑创建覆
索引如何优化Oracle的分组统计
2024-08-16

编程热搜

目录