首先感谢陈卫星老师的免费网络公开课,让我大致了解了sql的执行计划和相应的调优策略(这里主要讲的是思路)。
1.optimizer(oracle优化器相当于人的大脑)
优化器了解表中列数据的许多重要特征,最显著的是列值的选择性、聚簇因子、柱状图
optimizer_mode={choose|rule|first_rows|first_rows_n|all_rows}
choose|rule:列值的选择性
first_rows|first_rows_n|all_rows:10g后默认all_rows
first_rows:第一行返回结果最快
2.列值的选择性
oracle列值的选择性有2种:rule-based(10g后已淘汰,sysnax and data dictionary-driven)、cost-based(statistics-driven)
3.聚簇因子
聚簇因子就是描述表中的数据与存储区域相关性的一个因子(个人理解)
4.柱状图
优化器通过使用直方图,可以更准确的判断使用什么执行计划最优。
5.统计信息
统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息。比如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于统计信息。
1.parse
a.oracle 先搜索下共享池缓冲区,验证该语句是否执行过,如果是第一次执行,进入下一步
b.检查语法、权限、对象等等
c.oracle优化器会根据数据库存储的类型(partion iot cluster),根据统计信息,基于代价的原则,选择一条最佳路径编译并存储,以便共享
2.bind
绑定变量
3.execute
执行:从数据文件中读取数据块到数据缓冲区
4.fetch
把结果返回给用户
优化器根据表中列值的选择性、集簇因子、柱状图等重要特征决定是使用索引还是全表扫描。
(图1)
如果数据列具有高度的选择性和低的 clustering_factor,则索引扫描通常是最快的执行方法(参见图1)
(图2)
相反,高 clustering_factor 的数值达到表中的行数 (num_rows),表明这些行的顺序与索引中的顺序不同,索引范围扫描将会需要额外的 I/O。由于 clustering_factor 达到表中的行数,这些行与索引不同步。在此情况下,索引范围扫描会导致大量不必要的 I/O(参见图2 );全表扫描则会高效得多。
如果表行数据偏差比例比较大,选择柱状图,让优化器自动选择同一张表的不同条件对应不同执行方式
摘自CUUG+自己稍微加工