这个TABLE ACCESS STORAGE FULL的执行计划只有在ORACLE EXADATA上才回出现。
Oracle在Exadata上增加了一个硬件Exadata Programmable Storage Server,使得在存储系统可以变得更加智能。以往在进行全表扫描时,即使存在过滤条件,也需要将全部数据读到数据库服务器端,才能过滤掉无用的数据。但是通过这个硬件和存储软件的配合,使得这种过滤直接在存储层进行,而返回给数据库服务器的则是查询需要的结果。一方面在存储直接过滤提高访问性能,另一方面使得返回个服务器的数据量大大下降,这也是Exadata进行全表扫描性能优异的重要原因之一。
在昨天练手的时候,记录了一下这个执行计划,而这个执行计划在自己的测试环境中是不可能出现的:
SQL> SELECT COUNT(*) FROM t; COUNT(*) ---------- 49527761 Elapsed: 00:00:02.28 Execution Plan ---------------------------------------------------------- Plan hash VALUE: 2966233522 --------------------------------------------------------------------------- | Id | Operation | Name | ROWS | Cost (%CPU)| TIME | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 114K (1)| 00:22:59 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS STORAGE FULL| T | 228M| 114K (1)| 00:22:59 | --------------------------------------------------------------------------- Note ----- - dynamic sampling used FOR this statement (level=2) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 418736 consistent gets 0 physical reads 0 redo SIZE 529 bytes sent via SQL*Net TO client 524 bytes received via SQL*Net FROM client 2 SQL*Net roundtrips TO/FROM client 0 sorts (memory) 0 sorts (disk) 1 ROWS processed SQL> SELECT COUNT(*) FROM t WHERE owner = 'TEST'; COUNT(*) ---------- 611 Elapsed: 00:00:02.83 Execution Plan ---------------------------------------------------------- Plan hash VALUE: 2966233522 ----------------------------------------------------------------------------------- | Id | Operation | Name | ROWS | Bytes | Cost (%CPU)| TIME | ----------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 17 | 115K (2)| 00:23:07 | | 1 | SORT AGGREGATE | | 1 | 17 | | | |* 2 | TABLE ACCESS STORAGE FULL| T | 6670 | 110K| 115K (2)| 00:23:07 | ----------------------------------------------------------------------------------- Predicate Information (IDENTIFIED BY operation id): --------------------------------------------------- 2 - storage("OWNER"='TEST') FILTER("OWNER"='TEST') Note ----- - dynamic sampling used FOR this statement (level=2) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 418736 consistent gets 0 physical reads 0 redo SIZE 527 bytes sent via SQL*Net TO client 524 bytes received via SQL*Net FROM client 2 SQL*Net roundtrips TO/FROM client 0 sorts (memory) 0 sorts (disk) 1 ROWS processed |
可以看到Predicate Information中,访问和过滤条件分别是storage(“OWNER”=’TEST’)和filter(“OWNER”=’TEST’),这说明限制条件被推到了存储层执行,也正是这个原因,使得Oracle估算的访问行数没有太大的偏差。