Explain工具可以查看SQL语句的执行过程SQL索引的使用情况
explain plan for select id from abc where a='1'and b='1';
--查看索引使用情况(上条语句索引的使用情况)
select * from table(dbms_xplan.display);
如果是使用PLSQL的话,那就可以使用PLSQL提供的查询执行计划了,也就是按F5
参数如下:
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 446 | 667 | 00:00:09 |
| * 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 2 | 446 | 667 | 00:00:09 |
| * 3 | SORT ORDER BY STOPKEY | | 2 | 446 | 667 | 00:00:09 |
| 4 | VIEW | | 2 | 446 | 666 | 00:00:08 |
| 5 | UNION-ALL | | | | | |
| 6 | NESTED LOOPS OUTER | | 1 | 160 | 646 | 00:00:08 |
| 7 | NESTED LOOPS OUTER | | 1 | 128 | 637 | 00:00:08 |
| 8 | NESTED LOOPS OUTER | | 1 | 96 | 628 | 00:00:08 |
| 9 | NESTED LOOPS OUTER | | 1 | 75 | 624 | 00:00:08 |
| 10 | VIEW | | 1 | 54 | 620 | 00:00:08 |
| * 11 | FILTER | | | | | |
| 12 | HASH GROUP BY | | 1 | 74 | 620 | 00:00:08 |
| * 13 | TABLE ACCESS BY INDEX ROWID | BGT_JOURNAL_RESOURCE | 4 | 296 | 619 | 00:00:08 |
| * 14 | INDEX RANGE SCAN | BGT_JOURNAL_RESOURCE_N2 | 13026 | | 44 | 00:00:01 |
| 15 | VIEW PUSHED PREDICATE | | 1 | 21 | 4 | 00:00:01 |
| 16 | SORT GROUP BY | | 1 | 76 | 4 | 00:00:01 |
| * 17 | FILTER | | | | | |
| * 18 | TABLE ACCESS BY INDEX ROWID | BGT_EXECUTION_DETAIL | 1 | 76 | 4 | 00:00:01 |
| * 19 | INDEX RANGE SCAN | BGT_EXECUTION_DETAIL_N10 | 1 | | 3 | 00:00:01 |
| 20 | VIEW PUSHED PREDICATE | | 1 | 21 | 4 | 00:00:01 |
| 21 | SORT GROUP BY | | 1 | 76 | 4 | 00:00:01 |
| * 22 | FILTER | | | | | |
| * 23 | TABLE ACCESS BY INDEX ROWID | BGT_EXECUTION_DETAIL | 1 | 76 | 4 | 00:00:01 |
| * 24 | INDEX RANGE SCAN | BGT_EXECUTION_DETAIL_N10 | 1 | | 3 | 00:00:01 |
| * 25 | VIEW PUSHED PREDICATE | | 1 | 32 | 9 | 00:00:01 |
| 26 | SORT GROUP BY | | 1 | 115 | 9 | 00:00:01 |
| * 27 | FILTER | | | | | |
| 28 | NESTED LOOPS | | 1 | 115 | 8 | 00:00:01 |
| 29 | NESTED LOOPS | | 1 | 115 | 8 | 00:00:01 |
| * 30 | TABLE ACCESS BY INDEX ROWID | BGT_JOURNAL_RESOURCE | 1 | 76 | 7 | 00:00:01 |
| * 31 | INDEX RANGE SCAN | BGT_JOURNAL_RESOURCE_N1 | 4 | | 3 | 00:00:01 |
| * 32 | INDEX UNIQUE SCAN | SYS_C0016726 | 1 | | 0 | 00:00:01 |
| * 33 | TABLE ACCESS BY INDEX ROWID | BUDGET_CODE_COMBINATUONS | 1 | 39 | 1 | 00:00:01 |
| * 34 | VIEW PUSHED PREDICATE | | 1 | 32 | 9 | 00:00:01 |
| 35 | SORT GROUP BY | | 1 | 115 | 9 | 00:00:01 |
| * 36 | FILTER | | | | | |
| 37 | NESTED LOOPS | | 1 | 115 | 8 | 00:00:01 |
| 38 | NESTED LOOPS | | 1 | 115 | 8 | 00:00:01 |
| * 39 | TABLE ACCESS BY INDEX ROWID | BGT_JOURNAL_RESOURCE | 1 | 76 | 7 | 00:00:01 |
| * 40 | INDEX RANGE SCAN | BGT_JOURNAL_RESOURCE_N1 | 4 | | 3 | 00:00:01 |
| * 41 | INDEX UNIQUE SCAN | SYS_C0016726 | 1 | | 0 | 00:00:01 |
| * 42 | TABLE ACCESS BY INDEX ROWID | BUDGET_CODE_COMBINATUONS | 1 | 39 | 1 | 00:00:01 |
| 43 | NESTED LOOPS ANTI | | 1 | 448 | 20 | 00:00:01 |
| 44 | NESTED LOOPS ANTI | | 1 | 416 | 14 | 00:00:01 |
| 45 | NESTED LOOPS OUTER | | 1 | 384 | 8 | 00:00:01 |
| 46 | NESTED LOOPS OUTER | | 1 | 213 | 4 | 00:00:01 |
| 47 | VIEW | | 1 | 42 | 5 | 00:00:01 |
| 48 | HASH GROUP BY | | 1 | 66 | | |
| * 49 | FILTER | | | | | |
| 50 | TABLE ACCESS BY INDEX ROWID | BGT_EXECUTION_DETAIL | 1 | 66 | 4 | 00:00:01 |
| * 51 | INDEX RANGE SCAN | BGT_EXECUTION_DETAIL_N10 | 1 | | 3 | 00:00:01 |
| 52 | VIEW PUSHED PREDICATE | | 1 | 171 | 4 | 00:00:01 |
| 53 | SORT GROUP BY | | 1 | 76 | 4 | 00:00:01 |
| * 54 | FILTER | | | | | |
| * 55 | TABLE ACCESS BY INDEX ROWID | BGT_EXECUTION_DETAIL | 1 | 76 | 4 | 00:00:01 |
| * 56 | INDEX RANGE SCAN | BGT_EXECUTION_DETAIL_N10 | 1 | | 3 | 00:00:01 |
| 57 | VIEW PUSHED PREDICATE | | 1 | 171 | 4 | 00:00:01 |
| 58 | SORT GROUP BY | | 1 | 76 | 4 | 00:00:01 |
| * 59 | FILTER | | | | | |
| * 60 | TABLE ACCESS BY INDEX ROWID | BGT_EXECUTION_DETAIL | 1 | 76 | 4 | 00:00:01 |
| * 61 | INDEX RANGE SCAN | BGT_EXECUTION_DETAIL_N10 | 1 | | 3 | 00:00:01 |
| * 62 | TABLE ACCESS BY INDEX ROWID | BGT_JOURNAL_RESOURCE | 4611587 | 147570784 | 6 | 00:00:01 |
| * 63 | INDEX RANGE SCAN | BGT_JOURNAL_RESOURCE_N1 | 4 | | 2 | 00:00:01 |
| * 64 | TABLE ACCESS BY INDEX ROWID | BGT_JOURNAL_RESOURCE | 4611587 | 147570784 | 6 | 00:00:01 |
| * 65 | INDEX RANGE SCAN | BGT_JOURNAL_RESOURCE_N1 | 4 | | 2 | 00:00:01 |
----------------------------------------------
参数的意思:
基数(Rows):Oracle估计的当前步骤的返回结果集行数
字节(Bytes):执行SQL对应步骤返回的字节数
耗费(COST)、CPU耗费:Oracle估计的该步骤的执行耗费和CPU耗费
时间(Time):Oracle估计的执行sql对于步骤需要的时间
Oracle访问表中数据的方法有两种,一种是直接表中访问数据,另外一种是先访问索引,如果索引数据不符合目标SQL,就回表,符合就不回表,直接访问索引就可以。
Oracle直接访问表中数据的方法又分为两种:一种是全表扫描;另一种是ROWID扫描
访问索引(TABLE ACCESS BY INDEX SCAN)的情况就比较多了,可以分为:
索引范围扫描(INDEX RANGE SCAN)
索引范围扫描(INDEX RANGE SCAN)索引范围扫描(INDEX RANGE SCAN)适用于所有类型的B树索引,一般不包括唯一性索引,因为唯一性索引走索引唯一性扫描。 当扫描的对象是非唯一性索引的情况,where谓词条件为Between、=、<、>等等的情况就是索引范围扫描,注意,可以是等值查询,也可以是范围查询。如果where条件里有一个索引键值列没限定为非空的,那就可以走索引范围扫描,如果改索引列是非空的,那就走索引全扫描
前面说了,同样的SQL建的索引不同,就可能是走索引唯一性扫描,也有可能走索引范围扫描。在同等的条件下,索引范围扫描所需要的逻辑读和索引唯一性扫描对比,逻辑读如何?索引范围扫描可能返回多条记录,所以优化器为了确认,肯定会多扫描,所以在同等条件,索引范围扫描所需要的逻辑读至少会比相应的唯一性扫描的逻辑读多1
索引全扫描(INDEX FULL SCAN)
索引全扫描(INDEX FULL SCAN)适用于所有类型的B树索引(包括唯一性索引和非唯一性索引)。
索引全扫描过程简述:索引全扫描是指扫描目标索引所有叶子块的索引行,但不意思着需要扫描所有的分支块,索引全扫描时只需要访问必要的分支块,然后定位到位于改索引最左边的叶子块的第一行索引行,就可以利用改索引叶子块之间的双向指针链表,从左往右依次顺序扫描所有的叶子块的索引行
索引快速全扫描(INDEX FAST FULL SCAN)
索引快速全扫描和索引全扫描很类似,也适用于所有类型的B树索引(包括唯一性索引和非唯一性索引)。和索引全扫描类似,也是扫描所有叶子块的索引行,这些都是索引快速全扫描和索引全扫描的相同点
索引快速全扫描和索引全扫描区别:
索引快速全扫描只适应于CBO(基于成本的优化器)
索引快速全扫描可以使用多块读,也可以并行执行
索引全扫描会按照叶子块排序返回,而索引快速全扫描则是按照索引段内存储块顺序返回
索引快速全扫描的执行结果不一定是有序的,而索引全扫描的执行结果是有序的,因为索引快速全扫描是根据索引行在磁盘的物理存储顺序来扫描的,不是根据索引行的逻辑顺序来扫描的
索引跳跃式扫描(INDEX SKIP SCAN)
索引跳跃式扫描(INDEX SKIP SCAN)适用于所有类型的复合B树索引(包括唯一性索引和非唯一性索引),索引跳跃式扫描可以使那些在where条件中没有目标索引的前导列指定查询条件但是有索引的非前导列指定查询条件的目标SQL依然可以使用跳跃索引