通过Rowid访问单条数据最快的方式,在实际的引用中,首先从索引中收集ROWID,然后通过ROWID进行数据读取
索引访问方式
索引都可以看做一组符合主键和ROWID的组合,索引访问的目的是收集对目标快速读取时所需要的ROWID
B树索引,位图索引 基于函数的索引.
索引范围扫描:读取一个或者多个ROWID 索引数值升序排列
eg:select * from table where a = 'a';
快速全索引扫描
eg: select distinct color,count(*) from table group by color;
单个索引扫描:读取一个单独的ROWID
降序索引范围扫描:读取一个或者多个ROWID 索引数值降序排列
AND - EQUALS: select * from table where a = 'a' and b > 34; 从where字句中收集多个ROWID
连接操作
嵌套循环连接
散列连接
散列连接通常快于嵌套循环连接,特别是在驱动表以及在查询的where子句中过滤,只剩下少量的记录的情况下
排序合并连接
连接提示:
表反向连接提示,例如,NOT IN, NOT EXISTS 尽量避免使用 NOT IN 子句(它将调用子查询),而应该使用NOT EXISTS 子句(它将调用相关联的子查询), 因为如果子查询返回的任何一条记录中包含空值,那么该查询将不会返回记录,如果允许NOT IN 子句查询为空,那么 这种查询的性能非常的低,子查询会在外层查询块中对每一条记录重新执行一次。
排序大小 sort_area_size_init.ora 参数,在控制台查看 sort_area_size;
查询语句:show parameter sort_area_size;
磁盘排序的执行速度要比内存排序的的执行速度慢14000倍
磁盘排序之所以昂贵,有以下几个原因:
1,同在内存中进行排序比较,速度太慢
2,磁盘排序耗费临时表空间的资源
数据库分配2个临时表空间:
select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SYS';
select * from dba_temp_free_space;
Oracle临时表空间主要充当两个主要作用:临时表数据段分配和排序汇总溢出段。
排序汇总溢出的范围比较广泛。我们在SQL语句中进行order by/group by等操作,
首先是选择PGA的内存sort area、hash area和bitmap area。
如果SQL使用排序空间很高,单个server process对应的PGA不足以支撑排序要求的时候,临时表空间会充当排序段的数据写入。
而磁盘排序会降低单个任务的速度,同时还会影响Oracle实例中正在执行的其他任务,而且过多的磁盘排序将导致过多的空闲缓冲等待
以及将其他任务的数据块从缓冲池中分页出去的昂贵代价。
Oracle首先尝试在sort_area_size 分配的内存区中进行排序,Oracle只有不能再内存中排序时,才会调用磁盘排序
并将内存框架迁移到TEMP表空间,继续进行排序。
使用索引范围扫描的总体原则
-- 对于原始排序的表, 仅读取少于40%的表记录查询就应该使用索引范围扫描,反之,多余40%,使用全表扫。 -- 对于未排序的表, 仅读取少于7%的表记录查询就应该使用索引范围扫描,反之,多余7%,使用全表扫。
表的访问方式
sql优化器
对于任何一个sql语句来说,存在唯一的优化表访问方式,而你的工作就是找到这种方式,并且长期使用它。
db_file_multiblock_read_count
目的是为sql语句生成最快 并且好资源最少的执行计划
1,基于规则的优化器
步骤 对于在where子句中的每一个表 -- 生成一个可行的执行计划列表,这个列表中列出所有可以用来访问表的路径 -- 为每一个执行计划指定级别数值 -- 选择级别数值最低的计划 -- 对结果集的选择级别最低 连接方法进行评估 基于规则优化器(PBO)特征 - 总是使用索引,使用索引永远比使用全表扫描或使用排序合并连接(排序合并连接不需要索引)更加可取 - 总是从驱动表开始 在from字句的最后一个表是驱动表,在这个表中选择的记录数应该是最少(查询返回值最少),RBO在执行嵌套循环连接 操作时,将这个驱动表作为第一个操作表。 - 只有在不可避免的情况下才使用全表扫描 -任何索引都可以 - 有时越简单越好
2,基于成本的优化器(CBO)
基于规则优化提供更加复杂的优化替代方案 ANALYZE TABLE TT_TCAS_HK_QTY COMPUTE STATISTICS; ANALYZE TABLE TT_TCAS_HK_QTY ESTIMATE STATISTICS SAMPLE 5000 ROWS; ANALYZE TABLE TT_TCAS_HK_QTY ESTIMATE STATISTICS SAMPLE 5000 ROWS FOR ALL INDEXED COLUMNS; CBO在以下情况会选择错误的全表扫描 1,最高峰值过高 2,错误的optimizer_mode,如果optimizer_mode设置为all_rows,choose,那么sql优化器会倾向于使用全表扫描。 3,多表连接,存在多余3张表连接时,即使连接中存在索引,cbo仍然会对这些表进行全表扫描。 4,不平衡的索引分布,比如 color = 'blue' color字段上有索引,但是只有1%的记录属于blue,
SQL 的SGA统计资料
select name,value from v$sysstat where name like 'table%'
table scans(short table) -- 对小表全表扫描的次数
table scans(long table) -- 对大表全表扫描的次数,评估是否通过加索引减少大表的扫描次数 或者通过调用Oracle并行(opq)来提高查询的执行速度。
table scans Rows Gotten -- 这个数目说明全表扫描扫描记录条数
table scans blocks Gotten -- 扫描获取数据库的数目
Table fetch by rowid -- 通过索引访问记录的数目,这里的索引通常是嵌套循环连接
table fetch by Continued Row -- 这个数目说明与其他数据块连接在一起的记录数目
程序库缓存中可以多次使用的SQL
Oracle在辨认"相同的"sql语句是存在问题
例如:select from customer; Select From Customer; 尽管区别字母的大小写,Oracle会对第二个sql语句进行重新编译执行;