Understanding Optimizer Statistics (理解优化器统计信息) 读书笔记

Posted dingdingfish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Understanding Optimizer Statistics (理解优化器统计信息) 读书笔记相关的知识,希望对你有一定的参考价值。

本文为白皮书Understanding Optimizer Statistics (理解优化器统计信息) 的读书笔记。
此白皮书的后续第二部分为Best Practices for Gathering Optimizer Statistics
此白皮书的19c版本参考这里

简介

最初,决定如何执行SQL语句由RBO(Rule Based Optimizer)决定,Oracle 7以后改为由CBO(Cost Based Optimizer)决定。RBO是选择rank最低的,CBO则选择cost最低的。

cost 表示给定计划的估计资源使用量。 成本越低,执行计划的效率就越高。 为了让基于成本的优化器准确地确定一个执行计划的成本,它必须有关于在 SQL 语句中访问的所有对象(表和索引)的信息,以及关于将运行 SQL 语句的系统(CPU和I/O)的信息。这些信息被称为Optimizer statistics(优化器统计信息)。

了解和管理优化器统计信息是优化 SQL 执行的关键。 了解何时以及如何及时收集统计数据对于性能至关重要。

什么是Optimizer statistics

优化器统计信息是描述数据库和数据库中对象的数据集合。 优化器使用这些统计信息为每个 SQL 语句选择最佳执行计划。 统计信息存储在数据字典中,可以使用数据字典视图(例如 USER_TAB_STATISTICS)进行访问。 优化器统计信息与性能统计信息(V$ 视图)不同。 V$ 视图中的性能统计信息与系统状态和在其上执行的 SQL 工作负载有关。

表和列统计信息

表统计信息包括表中的行数、表使用的数据块数以及表中的平均行长等信息。 优化器使用此信息和其他统计信息来计算执行计划中各种操作的成本,并估计操作将产生的行数。相关的字典视图为USER_TAB_STATISTICS。

列统计信息包括有关列中不同值的数量 (NDV) 以及列中最小值和最大值的信息。优化器使用列统计信息和表统计信息(行数)来估计 SQL 操作将返回的行数。相关的字典视图为USER_TAB_COL_STATISTICS。

根据这里的描述:

Cardinality is the estimated number of rows the step will return.
A higher cardinality => you’re going to fetch more rows => you’re going to do more work => the query will take longer. Thus the cost is (usually) higher.

所以**Cardinality(基数)**越小越好。

额外的列统计信息

以上介绍的为基本统计信息。但是这些统计信息无法告诉优化器:列中是否存在数据倾斜(值偏离和范围偏离),或者表中的列之间是否存在相关性。 通过使用扩展统计信息(如直方图、列组和表达式统计数据),可以向优化器提供更详细的数据信息。

Histogram(直方图)

直方图的详细介绍参见这里

对于包含数据倾斜(列内数据的非均匀分布)的列,直方图使优化器能够为涉及这些列的过滤器和连接谓词生成准确的基数估计。

默认情况下,优化器假设列中不同值均匀分布。等于行数/列中的不同值的数量

Oracle 根据列使用信息 (SYS.COL_USAGE$) 和数据偏离的存在自动确定需要直方图的列。

直方图分为以下4种,系统会自动选择,如果想了解原理,白皮书中也给出了详细的解释:

  1. Frequency 和 top frequency
  2. Height-Balanced (legacy)
  3. Hybrid

扩展统计信息

包括列组(Column Groups)和表达式统计信息(Expression Statistics)。

先看列组。通过在一组列上创建统计信息,当同一表中的多个列在 SQL 语句的 where 子句中一起使用时,优化器可以计算出更好的基数估计。列组的统计信息通过DBMS_STATS.CREATE_EXTENDED_STATS创建。

表达式统计信息帮助优化器估计在表达式中嵌入了列的 where 子句谓词的基数。例如upper(col), col+2等。有一些现在,不详述了。

索引统计信息

索引统计信息提供关于索引中不同值的数量(不同的键)、索引的深度(blevel)、索引中的叶块数(leaf_blocks)和聚类因子的信息。 优化器将此信息与其他统计信息结合使用来确定索引访问的成本。

搜集统计信息

统计信息通过PL/SQL 包DBMS_STATS搜集。其中最重要的是GATHER_*_STATS过程。

GATHER_TABLE_STATS

帮助参考这里

主要参数说明:

  • ownname,null表示当前schema
  • estimate_percent,采样百分比,使用默认(DBMS_STATS.AUTO_SAMPLE_SIZE)就好。
  • method_opt,控制直方图统计信息,默认为FOR ALL COLUMNS SIZE AUTO,将AUTO改为1禁止直方图统计信息搜集。
  • degree,统计信息搜集的并行度
  • granularity,对于分区表的搜集粒度
  • cascade,是否搜集索引统计信息
  • no_invalidate,确定从属游标(访问正在重新收集统计信息的表的游标)是否在收集统计信息后立即失效。默认不会立即失效,系统在确定无性能影响时再将其置为无效。

修改GATHER_*_STATS参数的默认值

使用过程DBMS_STATS.SET_*_PREFS,分为不同的级别,如表、Schema、数据库和全局。

使用DBMS_STATS.GET_PREFS获取默认值。

自动统计信息搜集任务

参考这里,统计信息在维护窗口期内自动搜集。

参考这里,可以查看Predefined Maintenance Windows。

通过查看USER_TAB_STATISTICS的STALE_STATS列,可以确定表是否有最新的,或缺失统计信息。

对表的修改统计可参见USER_TAB_MODIFICATIONS。

统计信息陈旧时才会考虑重新搜集,这是由STALE_PERCENT控制的,默认是10%的行发生变化。

提升统计信息搜集的效率

使用并行,Parallel是针对1个表,Concurrent针对多个表和分区。

管理统计信息

恢复统计信息

搜集统计信息时,老的统计信息被保存,可通过DBMS_STATS.RESTORE_TABLE_STATS恢复,以防新信息出现问题。

待办统计信息

搜集完成后不发布。

导出/导入统计信息

主要用于模拟生产系统的测试。

比较统计信息

寻找差异。

锁定统计信息

避免采集新统计信息。

手工设定统计信息

使用DBMS_STATS.SET_*_STATS,通常不用于生产,可用于培训教学,检查优化器的行为。

其它类型的统计信息

略。

结论

为了让基于成本的优化器准确地确定执行计划的成本,它必须拥有 SQL 语句中访问的所有对象(表和索引)的信息,以及 SQL 语句运行所在系统的信息 . 此必要信息通常称为优化器统计信息。了解和管理统计信息是优化 SQL 执行的关键。 了解何时以及如何及时收集统计数据对于保持良好的性能至关重要。
通过结合使用自动统计信息收集作业和 DBMS_STATS 包,DBA 可以为系统维护一组准确的统计信息,确保优化器拥有最佳信息源来确定执行计划。

以上是关于Understanding Optimizer Statistics (理解优化器统计信息) 读书笔记的主要内容,如果未能解决你的问题,请参考以下文章

L177 Arctic ice brings an understanding of ancient Europe’s economy

Virtualization Essentials---Understanding hypervisor

Graying the black box: Understanding DQNs

在wamp 2.0环境下面安装Zend Optimizer的方法

PyTorch 101 Part 1: Understanding Graphs, Automatic Differentiation and Autograd

Pytorch框架学习---优化器Optimizer