建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

当前位置: 建站学 > 数据库 > Oracle教程 >

使用Oracle树形查询需要注意的一些问题(2)

时间:2011-03-20 09:20来源: 作者: 点击:
从前面的两个测试来看,优化器评估出来的SQL返回的行数要么是5739(表BSS_ORG的总行数),要么是6(总行数/BSS_PARENT_ORG_ID的Disctint Values)。但无论如何,随着不同的start with条件,这个行数(cardinality)与实际
  

从前面的两个测试来看,优化器评估出来的SQL返回的行数要么是5739(表BSS_ORG的总行数),要么是6(总行数/BSS_PARENT_ORG_ID的Disctint Values)。但无论如何,随着不同的start with条件,这个行数(cardinality)与实际返回的结果行数可能会存在非常大的差异。如果仅仅是测试中这样一个简单的SQL,实际上不会有什么问题,很容易出现问题的地方在于,一个复杂的SQL中,有类似于测试SQL这样的子查询,这样使得表连接的评估出现很大的偏差,这样容易引起非常大的性能问题。

  在9i下,如果BSS_PARENT_ORG_ID上如果没有索引,那么最后一个测试SQL的执行计划如下:

 SQL> explain plan for

  2 SELECT *

  3 FROM bss_org t

  4 START WITH bss_org_id = 832044754

  5 CONNECT BY bss_parent_org_id =

  6 PRIOR bss_org_id

  7 ;

  已解释。

  SQL> @showplan

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

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

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

  | 0 | SELECT STATEMENT | | 5739 | 297K| 9 |

  |* 1 | CONNECT BY WITH FILTERING | | | | |

  | 2 | TABLE ACCESS BY INDEX ROWID| BSS_ORG | | | |

  |* 3 | INDEX UNIQUE SCAN | PK_BSS_ORG | 1 | 7 | 1 |

  | 4 | HASH JOIN | | | | |

  | 5 | CONNECT BY PUMP | | | | |

  | 6 | TABLE ACCESS FULL | BSS_ORG | 5739 | 297K| 9 |

  | 7 | TABLE ACCESS FULL | BSS_ORG | 5739 | 297K| 9 |

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

  Predicate Information (identified by operation id):

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

  1 - filter("T"."BSS_ORG_ID"=832044754)

  3 - access("T"."BSS_ORG_ID"=832044754)

  SQL> explain plan for

  2 SELECT *

  3 FROM bss_org t

  4 START WITH bss_org_id = 832044754

  5 CONNECT BY bss_parent_org_id =

  6 PRIOR bss_org_id

  7 ;

  已解释。

  SQL> @showplan

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

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

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

  | 0 | SELECT STATEMENT | | 5739 | 297K| 9 |

  |* 1 | CONNECT BY WITH FILTERING | | | | |

  | 2 | TABLE ACCESS BY INDEX ROWID| BSS_ORG | | | |

  |* 3 | INDEX UNIQUE SCAN | PK_BSS_ORG | 1 | 7 | 1 |

  | 4 | HASH JOIN | | | | |

  | 5 | CONNECT BY PUMP | | | | |

  | 6 | TABLE ACCESS FULL | BSS_ORG | 5739 | 297K| 9 |

  | 7 | TABLE ACCESS FULL | BSS_ORG | 5739 | 297K| 9 |

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

  Predicate Information (identified by operation id):

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

  1 - filter("T"."BSS_ORG_ID"=832044754)

  3 - access("T"."BSS_ORG_ID"=832044754)
  这里9i的优化器评估出来的cardinality为5739,而11g与此同样的执行计划,评估的cardinality是6。

  前段时间就遇上由于connect by语句引起的性能问题。数据库为Oracle 9208,开始由于bss_org表的bss_parent_org_id列上没有索引,导致connect by部分得到的cardinality为5739,结果SQL性能非常差,在bss_parent_org_id上建索引后,执行计划改变,connect by 部分得到的cardinality为6,SQL性能大幅提升。

  对于Oracle优化器不能准确评估connect by 语句的cardinality,目前没有比较好的解决办法。必要的时候只有考虑使用Hint了。

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片