解释计划中的A行

时间:2016-08-15 13:44:28

标签: oracle

我试图理解为什么解释计划的A-rows列的行数(使用提示执行查询/ * + GATHER_PLAN_STATISTICS * /) 给了我一个远非真实的结果。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                       | Name                        | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 163 |                    TABLE ACCESS FULL            | LU_MY_TABLE                 |  29568 |   1017 |     31M|00:00:03.51 |    1094K|      0 |      0 |       |       |          |

似乎LU_MY_TABLE上有一个表访问权限,但是如果我这样做的话 来自LU_MY_TABLE的简单select count(*)结果为10169 ...

有人可以帮助我理解A-Rows吗?

谢谢和问候。 马可

1 个答案:

答案 0 :(得分:1)

A-Rows是该操作的所有启动产生的总行数。但E-Rows是对单次操作开始产生的行数的估计。您之前的评论是正确的 - 您可能希望将A-Rows除以Starts以确定基数估计值是否合适。

在您的示例中,Oracle估计每个操作运行1017行。但每次运行的实际行数为31M(A-Rows)/ 29568(Starts)= 1048(每次启动的实际行数)。这些数字非常接近。

(虽然我不明白为什么它们与表中的实际行数不同,10169。执行计划中Id旁边没有*因此没有明显的过滤那个表。但也许其他一些操作限制了结果。无论哪种方式,这都足以暗示Oracle正在很好地估计这个操作,所以问题可能是另一个步骤。)

测试架构

创建一个包含10行的表,然后运行一个对表进行10次计数的查询。

drop table test1 purge;
create table test1(a number);
insert into test1 select level from dual connect by level <= 10;
begin
    dbms_stats.gather_table_stats(user, 'TEST1');
end;
/

select /*+ gather_plan_statistics */ (select count(*) from test1 where a > b)
from (select - level b from dual connect by level <= 10);

select * from table(dbms_xplan.display_cursor(format => 'allstats last'));

<强>结果:

Id 2中的A行为100.这是每个全表扫描10行乘以10次。

(下面的计划略有修改以适应屏幕。)

Plan hash value: 2073232735

---------------------------------------------------------------------------------------
| Id  | Operation                     | Name  | Starts | E-Rows | A-Rows |   A-Time   |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |       |      1 |        |     10 |00:00:00.01 |
|   1 |  SORT AGGREGATE               |       |     10 |      1 |     10 |00:00:00.01 |
|*  2 |   TABLE ACCESS FULL           | TEST1 |     10 |      1 |    100 |00:00:00.01 |
|   3 |  VIEW                         |       |      1 |      1 |     10 |00:00:00.01 |
|   4 |   CONNECT BY WITHOUT FILTERING|       |      1 |        |     10 |00:00:00.01 |
|   5 |    FAST DUAL                  |       |      1 |      1 |      1 |00:00:00.01 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("A">:B1)