1.什么是驱动表?
- 通俗的讲就是先从哪个表开始检索啦,找到好的驱动表语句的优化就成功一半了
- eg: select * from a,b where a.id = b.id and a.姓名 = '美格瑞恩' and b.性别 = '女';在a,b表同等数量级的情况下显然用a表做为驱动表比较好因为姓名相对于性别来说可以过滤掉更多的数据,所以想办法使你的执行计划扫描a表先再通过nest loop与b表关连比较理想
2.RBO和CBO
- RBO中from后最后一张是驱动表,CBO中输出数据量最少的是驱动表。驱动表是基表,其他表是基于驱动表来嵌套。主要是调优时用的,考虑性能优化。
- RBO - 1、 基于规则的优化方式(Rule-Based Optimization,简称为RBO) 优化器
- CBO - 1、 基于代价的优化方式(Cost-Based Optimization,简称为CBO) 优化器
- 如果你是学DBA可能需要深入一些,如果你是技术开发,没有必要了解这么多。数据库是哪种优化器不是开发人员所能决定的。
3.oracle如何选择驱动表
- RBO或者CBO没有分析table的情况下,对于2个表的操作,FROM子句中,RBO选择最右的表作为驱动表(一般也就是from 中最后的表作为驱动表 )。 所以 对于NESTED LOOPS、HASH JOIN、SORT MERGE JOIN方式,驱动表选择较小的表 (放在from 最右端),速度会更快; 存在主、外键关系的表,由于主键由oracle自动建立索引,外键上最好也建索引,以避免全表扫描 。 而对于3个或以上table连接查询,对于FROM子句,RBO以从右到左的顺序处理表连接,也就是from 子句最右端table作为驱动表。
驱动表选择 http://blog.csdn.net/ys_565137671/article/details/6361730我们常说,
驱动表一定是小表,指的是根据条件获得的子集合一定要小,而不是说实体表本身一定要小,大表如果获得的子集合小,一样可以简称这个大表为驱动表。 ,
最好选择与其他表的主键字段进行比较,或者与已经索引的字段进行比较,这样一来,就有意识地将业务需求的主表,作为驱动表处理了,Oracle也会在选择最优执行计划时,比较容易的找到驱动表。如果WHERE条件过于复杂,或者业务上获得信息的主表并不容易确定,我们可以根据业务的实际情况,
评估关联各表的数据量和数据增长量,并分析关键条件字段的区分度,考虑在区分度高的字段,或者区分度高的组合字段上创建索引,以最大限度的降低某个表的结果集,增加其作为驱动表的机会。
4.oracle优化器的选择
- 优化模式包括 Rule、Choose、First rows、All rows 四种方式:
- Rule:基于规则的方式。
- Choolse:默认的情况下 Oracle 用的便是这种方式。指的是当一个表或或索引有统计信 息,则走 CBO 的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索 引时,那么就走索引,走 RBO 的方式。
- First Rows:它与 Choose 方式是类似的,所不同的是当一个表有统计信息时,它将是以 最快的方式返回查询的最先的几行,从总体上减少了响应时间。
- All Rows:也就是我们所说的 Cost 的方式,当一个表有统计信息时,它将以最快的方式 返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走 RBO 的方式。
- 设定选用哪种优化模式:
- A、Instance 级别我们可以通过在 initSID.ora 文件中设定 OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS 如果没设定 OPTIMIZER_MODE 参数则默认用的是 Choose 方式
- 。 B、Sessions 级别通过 ALTER SESSION SET OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS 来设定。
oracle的 session、共享、缓冲池、日志备份目录,都是通过这个设置的。
- [oracle@localhost oracleinstall]$ find . -type f -name "inityangkai.ora"
- ./oracle/product/db_yk/dbs/inityangkai.ora
- [oracle@localhost oracleinstall]$ cat ./oracle/product/db_yk/dbs/inityangkai.ora
- yangkai.__db_cache_size=176160768
- yangkai.__java_pool_size=4194304
- yangkai.__large_pool_size=4194304
- yangkai.__shared_pool_size=96468992
- yangkai.__streams_pool_size=0
- *.audit_file_dest='/oracleinstall/oracle/admin/yangkai/adump'
- *.background_dump_dest='/oracleinstall/oracle/admin/yangkai/bdump'
- *.compatible='10.2.0.1.0'
- *.control_files='/oracleinstall/oracle/oradata/yangkai/control01.ctl','/oracleinstall/oracle/oradata/yangkai/control02.ctl','/oracleinstall/oracle/oradata/yangkai/control03.ctl'
- *.core_dump_dest='/oracleinstall/oracle/admin/yangkai/cdump'
- *.db_block_size=8192
- *.db_domain=''
- *.db_file_multiblock_read_count=16
- *.db_name='yangkai'
- *.db_recovery_file_dest='/oracleinstall/oracle/flash_recovery_area'
- *.db_recovery_file_dest_size=2147483648
- *.dispatchers='(PROTOCOL=TCP) (SERVICE=yangkaiXDB)'
- *.job_queue_processes=10
- *.log_archive_start=TRUE
- *.open_cursors=300
- *.pga_aggregate_target=94371840
- *.processes=150
- *.remote_login_passwordfile='EXCLUSIVE'
- *.sga_target=285212672
- *.undo_management='AUTO'
- *.undo_tablespace='UNDOTBS1'
- *.user_dump_dest='/oracleinstall/oracle/admin/yangkai/udump'
- [oracle@localhost oracleinstall]$
- 关键的
- 是明白执行计划
- 而不在于记什么规则
- 举例,表连接返回一条记录
- 存在两个表,一个 10条记录 ,一个1000万条记录
- 若2表都存在连接字段索引,若以小表为驱动表,则
- 代价:
- 10* (通过索引在大表查询一条记录的代价)
- 若以大表为驱动表:
- 1000万 * (通过索引在小表中查询一条记录的代价)
- 通过索引获取一条记录,10rows的表,代价通常在 3 blocks
- 索引2块,表一块
- 而如果是1000万的表,索引可能达到4块表一块
- 这样一来参考上面的计算,你说哪个更好?很显然!
阅读(1916) | 评论(0) | 转发(0) |