视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
性能陷阱:Oracle表连接中范围比较
2020-11-09 12:18:33 责编:小采
文档


Lately, I met a case that the range filter predicates due to wrong cardinality issue. Letrsquo;s check the followin

  Lately, I met a case that the range filter predicates due to wrong cardinality issue. Let’s check the following query.

  最近遇到一个由于范围过滤导致错误基数而引起的性能问题。让我们来看下面的查询:

  The real records number is around 38,000,000.

  真实的记录数大约3千8百万

  The explain plan shows 72838, optimizer think it has good filtration. So put this JOIN in the first order. Actually , it is totally wrong.

  执行计划显示72838,这里优化器认为它有良好的过滤芯,所以把它放在一个多个表JOIN的第一位置。显然,,它完全错了。

  SQL> set autotrace traceonly explain;

  SQL> set linesize 999

  SQL> SELECT

  2 T.DURATIONSECSQTY TIMEINSECONDS,

  T.MONEYAMT MONEYAMOUNT,

  T.WAGEAMT WAGEAMOUNT,

  T.APPLYDTM APPLYDATE,

  T.ADJAPPLYDTM ADJUSTEDAPPLYDATE,

  T.STARTDTM,

  T.ENDDTM,

  T.HOMEACCOUNTSW

  FROM

  TKCSOWNER.WFCTOTAL T,

  TKCSOWNER.PAYCODE1MMFLAT MP

  WHERE

  MP.EFFECTIVEDTM <= T.APPLYDTM

  AND MP.EXPIRATIONDTM > T.APPLYDTM

  AND MP.PAYCODEID = T.PAYCODEID

  /

  ---------------------------------------------------------------------

  | Id | Operation | Name | Rows | Bytes | Cost |

  ---------------------------------------------------------------------

  | 0 | SELECT STATEMENT | | 72838 | 5192K| 37450 |

  |* 1 | HASH JOIN | | 72838 | 5192K| 37450 |

  | 2 | TABLE ACCESS FULL| PAYCODE1MMFLAT | 323 | 6783 | 3 |

  | 3 | TABLE ACCESS FULL| WFCTOTAL | 38K| 443M| 37317 |

  Now, let me comment the range filter.

  让我注释到范围条件看:

  “MP.EFFECTIVEDTM <= T.APPLYDTM

  AND MP.EXPIRATIONDTM > T.APPLYDTM”

  SQL> SELECT

  2 T.DURATIONSECSQTY TIMEINSECONDS,

  T.MONEYAMT MONEYAMOUNT,

  T.WAGEAMT WAGEAMOUNT,

  T.APPLYDTM APPLYDATE,

  T.ADJAPPLYDTM ADJUSTEDAPPLYDATE,

  T.STARTDTM,

  T.ENDDTM,

  T.HOMEACCOUNTSW

  FROM

  TKCSOWNER.WFCTOTAL T,

  TKCSOWNER.PAYCODE1MMFLAT MP

  WHERE

  /* MP.EFFECTIVEDTM <= T.APPLYDTM

  AND MP.EXPIRATIONDTM > T.APPLYDTM*/

  MP.PAYCODEID = T.PAYCODEID 3 4 5 6 7 8 9 10 11 12 13 14 15 16

  17 /

  Execution Plan

  ----------------------------------------------------------

  Plan hash value: 5403449

  ---------------------------------------------------------------------------

  | Id | Operation | Name | Rows | Bytes | Cost |

  ---------------------------------------------------------------------------

  | 0 | SELECT STATEMENT | | 29M| 1583M| 37405 |

  |* 1 | HASH JOIN | | 29M| 1583M| 37405 |

  | 2 | INDEX FAST FULL SCAN| PK_PAYCODE1MMFLAT | 323 | 1615 | 1 |

  | 3 | TABLE ACCESS FULL | WFCTOTAL | 38K| 443M| 37317 |

  The Cardinality show 29,135,142 , it is already close to the correct value.

  基础是29,135,142,已经接近正确结果了。

  So how optimizer work out the cardinality with range filter in TABLE JOIN ?

  那么优化器怎么出来表连接中的范围扫描呢?

  The answer is 5%, always 5%.

  答案是5%

  29135142 * 5% * 5% = 72837.8 , This is exact equal to the result of test 1.

  So if you meet any performance issue with range filter in TBALE JOIN, I am not surprise. I think Oracle need to improve the CBO to get better support on such situation.

下载本文
显示全文
专题