Oracle 12.1.2 等谓词基数错误,即使我收集了最新的 table 统计数据

Oracle 12.1.2 wrong cardinality on equal predicate even though I have gathered the latest table stats

以下示例是我尝试调整的查询的较小版本,因为我注意到计划的错误源于此特定操作。

select  count (*) from XVIEWMGR.XV_CASE_STAGES_DATA
where  stage_id = max_initial_or_reopen_id

如前所述,最近收集了 table 统计信息和相应的索引,但没有为每一列创建直方图,因为它们非常不同。我什至为这些列创建了扩展统计信息,但无济于事。

    OWNER                TABLE_NAME                       NUM_ROWS LAST_ANALYZED      
-------------------- ------------------------------ ---------- -------------------
XVIEWMGR             XV_CASE_STAGES_DATA                314079 09-11-2018 14:29:01


    TABLE_NAME                     COLUMN_NAME                    LAST_ANAL SAMPLE_SIZE  NUM_NULLS NUM_DISTINCT    DENSITY
------------------------------ ------------------------------ --------- ----------- ---------- ------------ ----------
XV_CASE_STAGES_DATA            STAGE_ID                       09-NOV-18      314079          0       308733 .00000323904474
XV_CASE_STAGES_DATA            MAX_INITIAL_OR_REOPEN_ID       09-NOV-18      314079          0       308728 .0000032390972

希望大家帮帮忙。

Dynamic statistics(也称为动态采样)非常擅长填补这样的空白。

测试设置:

create table xv_case_stages_data
( stage_id integer
, max_initial_or_reopen_id integer );

insert into xv_case_stages_data (stage_id, max_initial_or_reopen_id)
select rownum, rownum
from dual connect by rownum <= 1000;

commit;

call dbms_stats.gather_table_stats(user, 'XV_CASE_STAGES_DATA');

使用 xplanx.sql 在 12.2 中测试执行计划(为了便于阅读删除了一些输出):

SQL> select count (*) from xv_case_stages_data where stage_id = max_initial_or_reopen_id

SQL> @xplanx

Plan hash value: 1750917958

----------------------------------------------------------------------------------------------------
| Id  | Operation          | Name                | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                     |      1 |        |      1 |00:00:00.01 |       7 |
|   1 |  SORT AGGREGATE    |                     |      1 |      1 |      1 |00:00:00.01 |       7 |
|*  2 |   TABLE ACCESS FULL| XV_CASE_STAGES_DATA |      1 |      1 |   1000 |00:00:00.01 |       7 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("STAGE_ID"="MAX_INITIAL_OR_REOPEN_ID")

第 4 级动态采样:

SQL> select /*+ dynamic_sampling(4) */ count (*) from xv_case_stages_data where stage_id = max_initial_or_reopen_id

SQL> @xplanx

Plan hash value: 1750917958

----------------------------------------------------------------------------------------------------
| Id  | Operation          | Name                | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                     |      1 |        |      1 |00:00:00.01 |       7 |
|   1 |  SORT AGGREGATE    |                     |      1 |      1 |      1 |00:00:00.01 |       7 |
|*  2 |   TABLE ACCESS FULL| XV_CASE_STAGES_DATA |      1 |   1000 |   1000 |00:00:00.01 |       7 |
----------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("STAGE_ID"="MAX_INITIAL_OR_REOPEN_ID")

Note
-----
   - dynamic statistics used: dynamic sampling (level=4)