Optimizer_mode ALL_ROWS and FIRST_ROWS[_N]
Optimizer_mode是告诉query optimizer默认的优化途径,这个参数有三个参数,all_rows,first_rows_n,first_rows
• all_rows: The query optimizer uses a cost-based approach for all SQL statements and optimizes with a goal of best throughput (minimum resource cost to complete the entire statement).
• first_rows_n: The query optimizer uses a cost-based approach and optimizes with a goal of best response time to return the first n rows (where n = 1, 10, 100, or 1000).
• first_rows: The query optimizer uses a mix of costs and heuristics to find the best plan for quickly returning the first few rows.
all_rows是默认参数,first_rows只是为了向前兼容,ORACLE建议你平时用时使用first_rows_N,N的值越大就越像ALL_ROWS靠近。
你可以在分别instance,session,sql级指定优化级别,sql级使用hint,optimizer_mode不同也会生成不同的执行计划,有时对相同的sql为什么有的用索引有的不用,为什么有的是NL JOIN,为什么有的是HA JOIN
看个测试
create table bigtab pctfree 0 as select rownum id,rpad('anbob'||rownum,4000,'0') rname ,lpad('anbob'||rownum,4000,'0') lname from dual connect by ; rownum<100000; anbob@ANBOB> show parameter optimizer_mode NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ optimizer_mode string FIRST_ROWS anbob@ANBOB> select * from bigtab 2 left join obj on bigtab.id=obj.object_id 3 where obj.object_id between 1000 and 2000; 984 rows selected. Elapsed: 00:00:20.96 Execution Plan ---------------------------------------------------------- Plan hash value: 2217950213 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 940 | 7439K| 56128 (1)| 00:11:14 | | 1 | NESTED LOOPS | | | | | | | 2 | NESTED LOOPS | | 940 | 7439K| 56128 (1)| 00:11:14 | |* 3 | TABLE ACCESS FULL | BIGTAB | 1002 | 7834K| 54399 (1)| 00:10:53 | |* 4 | INDEX RANGE SCAN | IDX_OBJ_ID | 1 | | 1 (0)| 00:00:01 | | 5 | TABLE ACCESS BY INDEX ROWID| OBJ | 1 | 97 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------------------- anbob@ANBOB> alter session set optimizer_mode='ALL_ROWS'; Session altered. anbob@ANBOB> show parameter optimizer_mode NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ optimizer_mode string ALL_ROWS anbob@ANBOB> l 1 select * from bigtab 2 left join obj on bigtab.id=obj.object_id 3* where obj.object_id between 1000 and 2000 anbob@ANBOB> / 984 rows selected. Elapsed: 00:00:20.98 Execution Plan ---------------------------------------------------------- Plan hash value: 126369464 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 940 | 7439K| 54425 (1)| 00:10:54 | |* 1 | HASH JOIN | | 940 | 7439K| 54425 (1)| 00:10:54 | | 2 | TABLE ACCESS BY INDEX ROWID| OBJ | 941 | 91277 | 26 (0)| 00:00:01 | |* 3 | INDEX RANGE SCAN | IDX_OBJ_ID | 941 | | 4 (0)| 00:00:01 | |* 4 | TABLE ACCESS FULL | BIGTAB | 1002 | 7834K| 54399 (1)| 00:10:53 | ------------------------------------------------------------------------------------------- anbob@ANBOB> alter session set optimizer_mode='FIRST_ROWS'; Session altered. anbob@ANBOB> select /*+leading(bigtab)*/* from bigtab 2 left join obj on bigtab.id=obj.object_id 3 where obj.object_id between 1000 and 2000; 984 rows selected. Elapsed: 00:00:20.87 Execution Plan ---------------------------------------------------------- Plan hash value: 2217950213 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 940 | 7439K| 56128 (1)| 00:11:14 | | 1 | NESTED LOOPS | | | | | | | 2 | NESTED LOOPS | | 940 | 7439K| 56128 (1)| 00:11:14 | |* 3 | TABLE ACCESS FULL | BIGTAB | 1002 | 7834K| 54399 (1)| 00:10:53 | |* 4 | INDEX RANGE SCAN | IDX_OBJ_ID | 1 | | 1 (0)| 00:00:01 | | 5 | TABLE ACCESS BY INDEX ROWID| OBJ | 1 | 97 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------------------- 即使改变了join table order,也一样first_rows更倾向与NL JOIN; anbob@ANBOB> alter session set optimizer_mode='FIRST_ROWS_100'; Session altered. anbob@ANBOB> select * from bigtab 2 left join obj on bigtab.id=obj.object_id 3 where obj.object_id between 1000 and 2000 and rownum<10; 9 rows selected. Elapsed: 00:00:00.13 Execution Plan ---------------------------------------------------------- Plan hash value: 1237295455 -------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 9 | 141K| 5891 (1)| 00:01:11 | |* 1 | COUNT STOPKEY | | | | | | |* 2 | HASH JOIN | | 101 | 1589K| 5891 (1)| 00:01:11 | | 3 | TABLE ACCESS BY INDEX ROWID| OBJ | 941 | 91277 | 26 (0)| 00:00:01 | |* 4 | INDEX RANGE SCAN | IDX_OBJ_ID | 941 | | 4 (0)| 00:00:01 | |* 5 | TABLE ACCESS FULL | BIGTAB | 110 | 860K| 5865 (1)| 00:01:11 | -------------------------------------------------------------------------------------------- anbob@ANBOB> alter session set optimizer_mode='FIRST_ROWS_1'; Session altered. anbob@ANBOB> / 9 rows selected. Elapsed: 00:00:00.05 Execution Plan ---------------------------------------------------------- Plan hash value: 3152508579 -------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 16208 | 117 (1)| 00:00:02 | |* 1 | COUNT STOPKEY | | | | | | | 2 | NESTED LOOPS | | | | | | | 3 | NESTED LOOPS | | 2 | 16208 | 117 (1)| 00:00:02 | |* 4 | TABLE ACCESS FULL | BIGTAB | 4 | 32028 | 110 (0)| 00:00:02 | |* 5 | INDEX RANGE SCAN | IDX_OBJ_ID | 1 | | 1 (0)| 00:00:01 | | 6 | TABLE ACCESS BY INDEX ROWID| OBJ | 1 | 97 | 2 (0)| 00:00:01 | --------------------------------------------------------------------------------------------
FIRST_ROWS修改cbo,只是一种理想,返回第一行越快越好(ASAP),对于C/S环境,每次查询只返回几行来说它是不错的选择,比如TOAD,和SQLPLUS,同样一个查询你可能发现在TOAD运行很快就返回了记录(准确说是部分记录)其实它也是一直在fetch数据只不过in background,但SQLPLUS还在一直的滚动,first_rows_n,更倾向与index scan 和NS JOIN,适合用于OLTP。
ALL_ROWS对于INDEX FULL SCAN,和FULL TABLE SCAN来说是不错的,它是利用最大吞吐量返回更多的数据,在大数据集操作时更喜欢HA JOIN,更适合用于OLAP.
对不起,这篇文章暂时关闭评论。