如何强制优化器重用 sql 游标

Posted

技术标签:

【中文标题】如何强制优化器重用 sql 游标【英文标题】:How to force optimizer to reuse sql cursor 【发布时间】:2016-11-17 10:25:26 【问题描述】:

我们在 oracle 12c 中遇到了 oracle 优化器的问题。它需要多次执行 sql 语句,直到 sql 被标记为 IS_REOPTIMIZABLE=N

在 oracle11g/oracle12c 上输出相同的语句和几乎相同的数据。

-- output of v$sql (oracle 12c)
SQL_ID        CHILD_NUMBER  IS_REOPTIMIZABLE  IS_BIND_SENSITIVE ELAPSED_TIME  IS_BIND_AWARE IS_SHAREABLE  IS_OBSOLETE FETCHES EXECUTIONS  OPTIMIZER_COST  SQL_PLAN_BASELINE
0f83zdknhqsmj 1             Y                 N                 12575247      N             N             N           1       1           35              SQL_PLAN_3b0ugvyu8w97a4132b007
0f83zdknhqsmj 2             Y                 N                 78337268      N             N             N           1       1           35              SQL_PLAN_3b0ugvyu8w97a4132b007
0f83zdknhqsmj 3             Y                 N                 6079189       N             N             N           1       1           35              SQL_PLAN_3b0ugvyu8w97a4132b007
0f83zdknhqsmj 4             Y                 N                 6162748       N             N             N           1       1           35              SQL_PLAN_3b0ugvyu8w97a4132b007
0f83zdknhqsmj 5             Y                 N                 6647007       N             N             N           1       1           35              SQL_PLAN_3b0ugvyu8w97a4132b007
0f83zdknhqsmj 6             N                 N                 6939813       N             Y             N           3       3           35              SQL_PLAN_3b0ugvyu8w97a4132b007

-- output of v$sql (oracle 11g)
SQL_ID        CHILD_NUMBER                    IS_BIND_SENSITIVE ELAPSED_TIME  IS_BIND_AWARE IS_SHAREABLE  IS_OBSOLETE FETCHES EXECUTIONS  OPTIMIZER_COST  SQL_PLAN_BASELINE
0f83zdknhqsmj 0                               N                 2630792       N             Y             N           2       2           35              SQL_PLAN_3b0ugvyu8w97a4132b007

如你所见

经过时间在 oracle 12c 上非常糟糕。最后基线的执行计划总是被使用,这个计划已经足够好了。如果游标被重用(execution>=7),经过的时间大约是0.25秒

在 oracle 11g 上,游标立即被重用,在 oracle 12c 上,优化器需要 6 次尝试,直到它重用游标并且经过的时间可以接受。片刻之后,优化器重试优化 sql。

所以问题是: 我们并减少重新优化的工作量?

这里有一些可能需要的信息,如果您需要更多信息,请告诉我。 提前致谢!

    -- optimization hints
    select v.CHILD_NUMBER, v.HINT_ID, v.HINT_TEXT from V$SQL_REOPTIMIZATION_HINTS v where v.SQL_ID = '0f83zdknhqsmj';

    CHILD_NUMBER  HINT_ID HINT_TEXT
    5 1 OPT_ESTIMATE (@"SEL$8" TABLE "HEFTFOLGE"@"SEL$8" MIN=132.000000 ) 
    5 2 OPT_ESTIMATE (@"SEL$8" INDEX_FILTER "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=132.000000 ) 
    5 3 OPT_ESTIMATE (@"SEL$8" INDEX_SCAN "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=132.000000 ) 
    4 1 OPT_ESTIMATE (@"SEL$8" TABLE "HEFTFOLGE"@"SEL$8" MIN=578.000000 ) 
    4 2 OPT_ESTIMATE (@"SEL$8" INDEX_FILTER "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=578.000000 ) 
    4 3 OPT_ESTIMATE (@"SEL$8" INDEX_SCAN "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=578.000000 ) 
    3 1 OPT_ESTIMATE (@"SEL$8" TABLE "HEFTFOLGE"@"SEL$8" MIN=75.000000 ) 
    3 2 OPT_ESTIMATE (@"SEL$8" INDEX_FILTER "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=76.000000 ) 
    3 3 OPT_ESTIMATE (@"SEL$8" INDEX_SCAN "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=76.000000 ) 
    2 1 OPT_ESTIMATE (@"SEL$8" TABLE "HEFTFOLGE"@"SEL$8" MIN=730.000000 ) 
    2 2 OPT_ESTIMATE (@"SEL$8" INDEX_FILTER "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=730.000000 ) 
    2 3 OPT_ESTIMATE (@"SEL$8" INDEX_SCAN "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=730.000000 ) 
    1 1 OPT_ESTIMATE (@"SEL$8" TABLE "HEFTFOLGE"@"SEL$8" MIN=1644.000000 ) 
    1 2 OPT_ESTIMATE (@"SEL$8" INDEX_FILTER "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=1644.000000 ) 
    1 3 OPT_ESTIMATE (@"SEL$8" INDEX_SCAN "HEFTFOLGE"@"SEL$8" "PS_CS_HEFTFOLGE_TB" MIN=1644.000000 ) 

-- Optimizer settings
NAME  VALUE
plsql_optimize_level  2
optimizer_features_enable 12.1.0.2
optimizer_mode  ALL_ROWS
_optimizer_max_permutations 50
optimizer_index_cost_adj  20
optimizer_index_caching 0
optimizer_dynamic_sampling  4
optimizer_secure_view_merging TRUE
optimizer_use_pending_statistics  FALSE
optimizer_capture_sql_plan_baselines  FALSE
optimizer_use_sql_plan_baselines  TRUE
optimizer_use_invisible_indexes FALSE
optimizer_adaptive_reporting_only FALSE
optimizer_adaptive_features TRUE
optimizer_inmemory_aware  TRUE

-- Execution plan

SQL_ID  0f83zdknhqsmj, child number 6
-------------------------------------
SELECT CS_AUFTRAG_ID, CS_AUFPOS_SEQ, CS_AUFLIEF_SEQ, CS_AUFUNT_SEQ, 
CS_AUFUNT_SEQ_BEFR, CS_HEFTFOLGE_ID, SEQNO, CS_HEFTFOLGE, 
TO_CHAR(ACTUAL_PUB_DATE,'YYYY-MM-DD'), 
TO_CHAR(CS_VSSOLL_DT,'YYYY-MM-DD'), TO_CHAR(CS_VSIST_DT,'YYYY-MM-DD'), 
CS_ANZAHL_GEL, CS_MINLIEF, CS_YESNO_WV, CS_YESNO_LIEFERN, 
CS_BEFRIST_CD, CS_UNTERBR_CD, CS_UDGRUND_CD, CS_YESNO_LIEFEINST, 
CS_VERSART_CD, CS_KONDITION, CS_LIEFERMENGE, CS_PREIS, CURRENCY_CD, 
CS_YESNO_TERMADR, CS_KDNR_AS400, CS_ADR_LINE_1, CS_YESNO_NACHLIEF, 
TO_CHAR(CS_VSIST2_DT,'YYYY-MM-DD'), CS_ZUSTELLTYP_CD, CS_YN_HORIZONT 
FROM PS_CS_HEFTEREIT_VW WHERE CS_AUFTRAG_ID=:1 AND CS_AUFPOS_SEQ=:2 AND 
CS_AUFLIEF_SEQ=:3 ORDER BY CS_AUFTRAG_ID, CS_AUFPOS_SEQ, 
CS_AUFLIEF_SEQ, SEQNO

Plan hash value: 4191856942

-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                                    | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                                             |                    |       |       |    35 (100)|          |
|   1 |  SORT AGGREGATE                                              |                    |     1 |    43 |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID                                | PS_CS_AUFLIEF_AU   |     1 |    43 |     1   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                                          | PSACS_AUFLIEF_AU   |     1 |       |     1   (0)| 00:00:01 |
|   4 |  SORT ORDER BY                                               |                    |     1 |   916 |    35   (9)| 00:00:01 |
|*  5 |   FILTER                                                     |                    |       |       |            |          |
|   6 |    NESTED LOOPS OUTER                                        |                    |     1 |   916 |    31   (7)| 00:00:01 |
|   7 |     NESTED LOOPS OUTER                                       |                    |     1 |   866 |    30   (7)| 00:00:01 |
|   8 |      NESTED LOOPS OUTER                                      |                    |     1 |   798 |    29   (7)| 00:00:01 |
|   9 |       NESTED LOOPS                                           |                    |     1 |   708 |    28   (8)| 00:00:01 |
|  10 |        NESTED LOOPS                                          |                    |     1 |   640 |    27   (8)| 00:00:01 |
|  11 |         NESTED LOOPS OUTER                                   |                    |     1 |   550 |    26   (8)| 00:00:01 |
|  12 |          NESTED LOOPS OUTER                                  |                    |     1 |   512 |    25   (8)| 00:00:01 |
|  13 |           NESTED LOOPS OUTER                                 |                    |     1 |   469 |    24   (9)| 00:00:01 |
|  14 |            NESTED LOOPS OUTER                                |                    |     1 |   411 |    23   (9)| 00:00:01 |
|  15 |             VIEW                                             |                    |     1 |   346 |    22  (10)| 00:00:01 |
|  16 |              NESTED LOOPS OUTER                              |                    |     1 |   443 |    22  (10)| 00:00:01 |
|* 17 |               VIEW                                           |                    |     1 |   386 |    21  (10)| 00:00:01 |
|  18 |                WINDOW SORT                                   |                    |     1 |   540 |    21  (10)| 00:00:01 |
|  19 |                 NESTED LOOPS OUTER                           |                    |     1 |   540 |    20   (5)| 00:00:01 |
|  20 |                  NESTED LOOPS OUTER                          |                    |     1 |   488 |    19   (6)| 00:00:01 |
|  21 |                   NESTED LOOPS OUTER                         |                    |     1 |   424 |    18   (6)| 00:00:01 |
|  22 |                    NESTED LOOPS OUTER                        |                    |     1 |   374 |    17   (6)| 00:00:01 |
|  23 |                     NESTED LOOPS OUTER                       |                    |     1 |   322 |    16   (7)| 00:00:01 |
|  24 |                      VIEW                                    |                    |     1 |   264 |    15   (7)| 00:00:01 |
|  25 |                       WINDOW BUFFER                          |                    |     1 |   254 |    15   (7)| 00:00:01 |
|  26 |                        VIEW                                  |                    |     1 |   254 |    15   (7)| 00:00:01 |
|  27 |                         WINDOW SORT                          |                    |     1 |   532 |    15   (7)| 00:00:01 |
|  28 |                          NESTED LOOPS OUTER                  |                    |     1 |   532 |    13   (0)| 00:00:01 |
|  29 |                           NESTED LOOPS                       |                    |     1 |   503 |    12   (0)| 00:00:01 |
|  30 |                            NESTED LOOPS OUTER                |                    |     1 |   474 |    11   (0)| 00:00:01 |
|  31 |                             NESTED LOOPS OUTER               |                    |     1 |   445 |    10   (0)| 00:00:01 |
|  32 |                              NESTED LOOPS                    |                    |     1 |   390 |     9   (0)| 00:00:01 |
|  33 |                               NESTED LOOPS OUTER             |                    |     1 |   303 |     8   (0)| 00:00:01 |
|  34 |                                NESTED LOOPS                  |                    |     1 |   258 |     7   (0)| 00:00:01 |
|  35 |                                 NESTED LOOPS                 |                    |     1 |   240 |     6   (0)| 00:00:01 |
|  36 |                                  NESTED LOOPS                |                    |     1 |   198 |     5   (0)| 00:00:01 |
|  37 |                                   NESTED LOOPS               |                    |     1 |   171 |     4   (0)| 00:00:01 |
|  38 |                                    VIEW                      |                    |     1 |   143 |     3   (0)| 00:00:01 |
|  39 |                                     NESTED LOOPS             |                    |     1 |   179 |     3   (0)| 00:00:01 |
|  40 |                                      NESTED LOOPS            |                    |     1 |    92 |     2   (0)| 00:00:01 |
|  41 | ROWID                                 TABLE ACCESS BY INDEX  | PS_CS_AUFTRAG_TB   |     1 |    41 |     1   (0)| 00:00:01 |
|* 42 |                                        INDEX UNIQUE SCAN     | PS_CS_AUFTRAG_TB   |     1 |       |     1   (0)| 00:00:01 |
|  43 | ROWID                                 TABLE ACCESS BY INDEX  | PS_CS_AUFPOS_TB    |     1 |    51 |     1   (0)| 00:00:01 |
|* 44 |                                        INDEX UNIQUE SCAN     | PS_CS_AUFPOS_TB    |     1 |       |     1   (0)| 00:00:01 |
|  45 | OWID                                 TABLE ACCESS BY INDEX R | PS_CS_AUFLIEF_TB   |     1 |    87 |     1   (0)| 00:00:01 |
|* 46 |                                       INDEX UNIQUE SCAN      | PS_CS_AUFLIEF_TB   |     1 |       |     1   (0)| 00:00:01 |
|  47 | ID                                 TABLE ACCESS BY INDEX ROW | PS_CS_ARTIKEL_TB   |     1 |    28 |     1   (0)| 00:00:01 |
|* 48 |                                     INDEX UNIQUE SCAN        | PS_CS_ARTIKEL_TB   |     1 |       |     1   (0)| 00:00:01 |
|  49 | D                                 TABLE ACCESS BY INDEX ROWI | PS_CS_OBJEINW_TB   |     1 |    27 |     1   (0)| 00:00:01 |
|* 50 |                                    INDEX UNIQUE SCAN         | PS_CS_OBJEINW_TB   |     1 |       |     1   (0)| 00:00:01 |
|  51 |                                  TABLE ACCESS BY INDEX ROWID | PS_CS_MANDOBJ_TB   |     1 |    42 |     1   (0)| 00:00:01 |
|* 52 |                                   INDEX UNIQUE SCAN          | PS_CS_MANDOBJ_TB   |     1 |       |     1   (0)| 00:00:01 |
|  53 |                                 TABLE ACCESS BY INDEX ROWID  | PS_CS_OBJSTEUER_TB |     1 |    18 |     1   (0)| 00:00:01 |
|* 54 |                                  INDEX RANGE SCAN            | PS_CS_OBJSTEUER_TB |     1 |       |     1   (0)| 00:00:01 |
|  55 |                                   SORT AGGREGATE             |                    |     1 |    12 |            |          |
|  56 |                                    FIRST ROW                 |                    |     1 |    12 |     1   (0)| 00:00:01 |
|* 57 | X)                                  INDEX RANGE SCAN (MIN/MA | PS_CS_OBJSTEUER_TB |     1 |    12 |     1   (0)| 00:00:01 |
|  58 |                                TABLE ACCESS BY INDEX ROWID   | PS_CS_AKT_PROD_TB  |     1 |    45 |     1   (0)| 00:00:01 |
|* 59 |                                 INDEX UNIQUE SCAN            | PS_CS_AKT_PROD_TB  |     1 |       |     1   (0)| 00:00:01 |
|* 60 |                               TABLE ACCESS BY INDEX ROWID    | PS_CS_HEFTFOLGE_TB |     6 |   522 |     1   (0)| 00:00:01 |
|* 61 |                                INDEX RANGE SCAN              | PS_CS_HEFTFOLGE_TB |     2 |       |     1   (0)| 00:00:01 |
|  62 |                              TABLE ACCESS BY INDEX ROWID     | PS_CS_HEFTFOLGE_TB |     1 |    55 |     1   (0)| 00:00:01 |
|* 63 |                               INDEX UNIQUE SCAN              | PS_CS_HEFTFOLGE_TB |     1 |       |     1   (0)| 00:00:01 |
|  64 |                             TABLE ACCESS BY INDEX ROWID      | PS_CS_HEFTFOLGE_TB |     1 |    29 |     1   (0)| 00:00:01 |
|* 65 |                              INDEX RANGE SCAN                | PS0CS_HEFTFOLGE_TB |     1 |       |     1   (0)| 00:00:01 |
|  66 |                            TABLE ACCESS BY INDEX ROWID       | PS_CS_HEFTFOLGE_TB |     1 |    29 |     1   (0)| 00:00:01 |
|* 67 |                             INDEX RANGE SCAN                 | PS0CS_HEFTFOLGE_TB |     1 |       |     1   (0)| 00:00:01 |
|  68 |                           TABLE ACCESS BY INDEX ROWID        | PS_CS_HEFTFOLGE_TB |     1 |    29 |     1   (0)| 00:00:01 |
|* 69 |                            INDEX RANGE SCAN                  | PS0CS_HEFTFOLGE_TB |     1 |       |     1   (0)| 00:00:01 |
|* 70 |                      TABLE ACCESS BY INDEX ROWID             | PS_CS_SRY_REKLA_TB |     1 |    58 |     1   (0)| 00:00:01 |
|* 71 |                       INDEX RANGE SCAN                       | PSCCS_SRY_REKLA_TB |     1 |       |     1   (0)| 00:00:01 |
|* 72 |                     TABLE ACCESS BY INDEX ROWID              | PS_CS_AUFUNT_TB    |     1 |    52 |     1   (0)| 00:00:01 |
|* 73 |                      INDEX RANGE SCAN                        | PS_CS_AUFUNT_TB    |     1 |       |     1   (0)| 00:00:01 |
|* 74 |                    TABLE ACCESS BY INDEX ROWID               | PS_CS_AUFUNT_TB    |     1 |    50 |     1   (0)| 00:00:01 |
|* 75 |                     INDEX RANGE SCAN                         | PS_CS_AUFUNT_TB    |     1 |       |     1   (0)| 00:00:01 |
|* 76 |                   TABLE ACCESS BY INDEX ROWID                | PS_CS_AUFUNT_TB    |     1 |    64 |     1   (0)| 00:00:01 |
|* 77 |                    INDEX RANGE SCAN                          | PS_CS_AUFUNT_TB    |     1 |       |     1   (0)| 00:00:01 |
|* 78 |                  TABLE ACCESS BY INDEX ROWID                 | PS_CS_AUFUNT_TB    |     1 |    52 |     1   (0)| 00:00:01 |
|* 79 |                   INDEX RANGE SCAN                           | PS_CS_AUFUNT_TB    |     1 |       |     1   (0)| 00:00:01 |
|* 80 |               TABLE ACCESS BY INDEX ROWID                    | PS_CS_AUFVERS_TB   |     1 |    57 |     1   (0)| 00:00:01 |
|* 81 |                INDEX RANGE SCAN                              | PS_CS_AUFVERS_TB   |     2 |       |     1   (0)| 00:00:01 |
|  82 |             TABLE ACCESS BY INDEX ROWID                      | PS_CS_WVS_HFOLG_TB |     1 |    65 |     1   (0)| 00:00:01 |
|* 83 |              INDEX UNIQUE SCAN                               | PS_CS_WVS_HFOLG_TB |     1 |       |     1   (0)| 00:00:01 |
|  84 |            TABLE ACCESS BY INDEX ROWID                       | PS_CS_VERSTRACK_TB |     1 |    58 |     1   (0)| 00:00:01 |
|* 85 |             INDEX RANGE SCAN                                 | PS1CS_VERSTRACK_TB |     1 |       |     1   (0)| 00:00:01 |
|* 86 |           TABLE ACCESS BY INDEX ROWID                        | PS_CS_AUFPOS_TB    |     1 |    43 |     1   (0)| 00:00:01 |
|* 87 |            INDEX RANGE SCAN                                  | PSBCS_AUFPOS_TB    |     1 |       |     1   (0)| 00:00:01 |
|  88 |          TABLE ACCESS BY INDEX ROWID                         | PS_CS_AUFLIEF_TB   |     1 |    38 |     1   (0)| 00:00:01 |
|* 89 |           INDEX RANGE SCAN                                   | PS_CS_AUFLIEF_TB   |     1 |       |     1   (0)| 00:00:01 |
|  90 |         TABLE ACCESS BY INDEX ROWID                          | PS_CS_AUFADR_TB    |     1 |    90 |     1   (0)| 00:00:01 |
|* 91 |          INDEX UNIQUE SCAN                                   | PS_CS_AUFADR_TB    |     1 |       |     1   (0)| 00:00:01 |
|  92 |           SORT AGGREGATE                                     |                    |     1 |    49 |            |          |
|* 93 |            TABLE ACCESS BY INDEX ROWID                       | PS_CS_AUFADR_TB    |     1 |    49 |     1   (0)| 00:00:01 |
|* 94 |             INDEX RANGE SCAN                                 | PS_CS_AUFADR_TB    |     1 |       |     1   (0)| 00:00:01 |
|  95 |        TABLE ACCESS BY INDEX ROWID                           | PS_CS_ADRART_TB    |     1 |    68 |     1   (0)| 00:00:01 |
|* 96 |         INDEX RANGE SCAN                                     | PS_CS_ADRART_TB    |     1 |       |     1   (0)| 00:00:01 |
|  97 |          SORT AGGREGATE                                      |                    |     1 |    70 |            |          |
|* 98 |           TABLE ACCESS BY INDEX ROWID                        | PS_CS_ADRART_TB    |     1 |    70 |     1   (0)| 00:00:01 |
|* 99 |            INDEX RANGE SCAN                                  | PS_CS_ADRART_TB    |     1 |       |     1   (0)| 00:00:01 |
| 100 |       TABLE ACCESS BY INDEX ROWID                            | PS_CS_AUFADR_TB    |     1 |    90 |     1   (0)| 00:00:01 |
|*101 |        INDEX RANGE SCAN                                      | PS_CS_AUFADR_TB    |     1 |       |     1   (0)| 00:00:01 |
| 102 |      TABLE ACCESS BY INDEX ROWID                             | PS_CS_ADRART_TB    |     1 |    68 |     1   (0)| 00:00:01 |
|*103 |       INDEX RANGE SCAN                                       | PS_CS_ADRART_TB    |     1 |       |     1   (0)| 00:00:01 |
| 104 |     TABLE ACCESS BY INDEX ROWID                              | PS_CS_AUFLIEFDT_TB |     1 |    50 |     1   (0)| 00:00:01 |
|*105 |      INDEX RANGE SCAN                                        | PS_CS_AUFLIEFDT_TB |     1 |       |     1   (0)| 00:00:01 |
| 106 |    SORT AGGREGATE                                            |                    |     1 |    36 |            |          |
| 107 |     FIRST ROW                                                |                    |     1 |    36 |     1   (0)| 00:00:01 |
|*108 |      INDEX RANGE SCAN (MIN/MAX)                              | PS_CS_AUFLIEFDT_TB |     1 |    36 |     1   (0)| 00:00:01 |
| 109 |    SORT AGGREGATE                                            |                    |     1 |    49 |            |          |
|*110 |     TABLE ACCESS BY INDEX ROWID                              | PS_CS_AUFADR_TB    |     1 |    49 |     1   (0)| 00:00:01 |
|*111 |      INDEX RANGE SCAN                                        | PS_CS_AUFADR_TB    |     1 |       |     1   (0)| 00:00:01 |
| 112 |    SORT AGGREGATE                                            |                    |     1 |    70 |            |          |
|*113 |     TABLE ACCESS BY INDEX ROWID                              | PS_CS_ADRART_TB    |     1 |    70 |     1   (0)| 00:00:01 |
|*114 |      INDEX RANGE SCAN                                        | PS_CS_ADRART_TB    |     1 |       |     1   (0)| 00:00:01 |
| 115 |    SORT AGGREGATE                                            |                    |     1 |    43 |            |          |
|*116 |     FILTER                                                   |                    |       |       |            |          |
|*117 |      TABLE ACCESS BY INDEX ROWID                             | PS_CS_AUFPOS_TB    |     1 |    43 |     1   (0)| 00:00:01 |
|*118 |       INDEX RANGE SCAN                                       | PSBCS_AUFPOS_TB    |     1 |       |     1   (0)| 00:00:01 |
| 119 |      SORT AGGREGATE                                          |                    |     1 |    39 |            |          |
|*120 |       TABLE ACCESS BY INDEX ROWID                            | PS_CS_AUFPOS_TB    |     1 |    39 |     1   (0)| 00:00:01 |
|*121 |        INDEX RANGE SCAN                                      | PSBCS_AUFPOS_TB    |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------------------------
    Note
    -----
       - dynamic statistics used: dynamic sampling (level=4)
       - SQL plan baseline SQL_PLAN_3b0ugvyu8w97a4132b007 used for this statement
       - statistics feedback used for this statement

【问题讨论】:

优化器估计每个表只有 1 行。当你收集统计数据时它会改变吗? 将 SQL 计划基线设置为 FIXED 是否有帮助? PS_CS_HEFTFOLGE_TB 及其索引的统计信息是最新的。尽管如此,优化器估计“E-Rows=6”。有效结果为A-Rows=201 不,将 SQL 计划基线设置为 FIXED 没有帮助。 【参考方案1】:

一般情况下,您可以运行以下 SQL:

select * from v$sql_shared_cursor
where sql_id = '0f83zdknhqsmj';

它会告诉你为什么 Oracle 不重用现有的子游标。

在您的特定情况下,您似乎已经知道不重用的原因是 Oracle 由于基数不匹配而重新优化查询,您可以直接进入此查询:

select * 
from V$SQL_REOPTIMIZATION_HINTS 
where  sql_id = '0f83zdknhqsmj';

这应该让您深入了解基数不匹配涉及哪个计划步骤。

【讨论】:

谢谢,我已经检查了这些观点,你可以在我的问题末尾看到。问题是如何强制优化器立即使用基线 sql 重用现有游标。 你没有发布足够的信息让我在这里给你一个确凿的证据。我所能做的就是建议您使用该技术,即使用V$SQL_REOPTIMIZATION_HINTSalter session set statistics_level = ALL 加上DBMS_XPLAN.display_cursor 来确定Oracle 在其初始基数估计中出错的地方。然后,使用dbms_stats.create_extended_statistics 后跟dbms_stats.gather_table_stats 收集扩展(多列)统计信息,以便Oracle 的CBO 获得第一次做出正确基数估计所需的信息。 谢谢,我想我应该试试dbms_stats.create_extended_statistics 祝你好运。为获得最佳结果,如果列中的数据有偏差,请务必使用直方图(使用 method_opt 参数)收集扩展统计信息。 这种方法是正确的,它有助于解决谓词引用同一个表的多个列的问题。

以上是关于如何强制优化器重用 sql 游标的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 优化器自适应游标共享(Adaptive Cursor Sharing)功能

Oracle 优化器SQL计划指令(SQL Plan Directives)

查询优化器

Spark 催化剂优化器强制转换异常

如何优化使用游标的 PL/SQL 代码

SQL -- SQL Server 查询优化器(Query Optimizers)