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

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

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

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

时间:2011-03-20 09:20来源: 作者: 点击:
Oracle提供了方便的树形查询功能,也就是connect by 语句。树形结构是很常见的,比如组织机构树,产品目录树等。本文不讲述connect by 如何使用,只是提出在使用树形查询时需要考虑的一个有关于性能方面的问题。   这里提到的问题,主要是Oracle优化器在评估connect

Oracle树形查询功能,也就是connect by语句使用起来非常方便。树形结构是很常见的,比如组织机构树,产品目录树等。我们这里不讲述connect by 如何使用,只是提出在使用树形查询时需要考虑的一个有关于性能方面的问题。
  这里提到的问题,主要是Oracle优化器在评估connect by 语句的cardinality时,存在的缺陷,下面将举例说明。

  在这个例子中所使用的表,是一个真实的生产系统中的表,BSS_ORG: 

SQL> desc bss_org

  名称 是否为空? 类型

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

  BSS_ORG_ID NOT NULL NUMBER(9)

  NAME NOT NULL VARCHAR2(64)

  BSS_PARENT_ORG_ID NUMBER(9)

  BSS_ORG_LEVEL_ID NOT NULL NUMBER(3)

  STATE NOT NULL VARCHAR2(3)

  STATE_DATE DATE

  BSS_ORG_CODE VARCHAR2(15)
  在这个BSS_ORG表中,BSS_ORG_ID是主键,BSS_PARENT_ORG_ID与BSS_ORG_ID形成上下层级关系。这个表的统计信息如下: 

Table Number Empty Average Chain Average Global

  Name of Rows Blocks Blocks Space Count Row Len Stats

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

  BSS_ORG 5,739 52 0 0 0 53 YES

  Column Column Distinct Number

  Name Details Values Density Buckets

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

  BSS_ORG_ID NUMBER(9,0) NOT NULL 5,739 .000174 1

  NAME VARCHAR2(64) NOT NULL 5,034 .000361 200

  BSS_PARENT_ORG_ID NUMBER(9,0) 905 .002189 200

  BSS_ORG_LEVEL_ID NUMBER(3,0) NOT NULL 6 .000087 6

  STATE VARCHAR2(3) NOT NULL 2 .000087 2

  STATE_DATE DATE 1,624 .001434 200

  BSS_ORG_CODE VARCHAR2(15) 5,639 .000179 200

  Table Number Empty Average Chain Average Global

  Name of Rows Blocks Blocks Space Count Row Len Stats

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

  BSS_ORG 5,739 52 0 0 0 53 YES

  Column Column Distinct Number

  Name Details Values Density Buckets

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

  BSS_ORG_ID NUMBER(9,0) NOT NULL 5,739 .000174 1

  NAME VARCHAR2(64) NOT NULL 5,034 .000361 200

  BSS_PARENT_ORG_ID NUMBER(9,0) 905 .002189 200

  BSS_ORG_LEVEL_ID NUMBER(3,0) NOT NULL 6 .000087 6

  STATE VARCHAR2(3) NOT NULL 2 .000087 2

  STATE_DATE DATE 1,624 .001434 200

  BSS_ORG_CODE VARCHAR2(15) 5,639 .000179 200
  下面的测试,是在Oracle 11.1.0.6 for Windows版本下进行的测试。在Oracle 9i、Oracle 10g下测试的结果与Oracle 11g下测试的结果是相符的。当然这里谈到的问题是cardinality,因此在三个版本下,SQL的执行计划可能有所不同,但最终的结论是一致的。(BTW:从10g开始,connect by语句有一个新的执行步骤,称为CONNECT BY NO FILTERING,对应的Hint是no_connect_by_filtering)。

Table Number Empty Average Chain Average Global

  Name of Rows Blocks Blocks Space Count Row Len Stats

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

  BSS_ORG 5,739 52 0 0 0 53 YES

  Column Column Distinct Number

  Name Details Values Density Buckets

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

  BSS_ORG_ID NUMBER(9,0) NOT NULL 5,739 .000174 1

  NAME VARCHAR2(64) NOT NULL 5,034 .000361 200

  BSS_PARENT_ORG_ID NUMBER(9,0) 905 .002189 200

  BSS_ORG_LEVEL_ID NUMBER(3,0) NOT NULL 6 .000087 6

  STATE VARCHAR2(3) NOT NULL 2 .000087 2

  STATE_DATE DATE 1,624 .001434 200

  BSS_ORG_CODE VARCHAR2(15) 5,639 .000179 200

  Table Number Empty Average Chain Average Global

  Name of Rows Blocks Blocks Space Count Row Len Stats

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

  BSS_ORG 5,739 52 0 0 0 53 YES

  Column Column Distinct Number

  Name Details Values Density Buckets

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

  BSS_ORG_ID NUMBER(9,0) NOT NULL 5,739 .000174 1

  NAME VARCHAR2(64) NOT NULL 5,034 .000361 200

  BSS_PARENT_ORG_ID NUMBER(9,0) 905 .002189 200

  BSS_ORG_LEVEL_ID NUMBER(3,0) NOT NULL 6 .000087 6

  STATE VARCHAR2(3) NOT NULL 2 .000087 2

  STATE_DATE DATE 1,624 .001434 200

  BSS_ORG_CODE VARCHAR2(15) 5,639 .000179 200
  上面的2条SQL,第1条实际应该返回的行数为5739,第2条SQL实际应该返回的行数为4,但是从执行计划上看,Oracle优化器评估的行数均为5739。

Table Number Empty Average Chain Average Global

  Name of Rows Blocks Blocks Space Count Row Len Stats

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

  BSS_ORG 5,739 52 0 0 0 53 YES

  Column Column Distinct Number

  Name Details Values Density Buckets

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

  BSS_ORG_ID NUMBER(9,0) NOT NULL 5,739 .000174 1

  NAME VARCHAR2(64) NOT NULL 5,034 .000361 200

  BSS_PARENT_ORG_ID NUMBER(9,0) 905 .002189 200

  BSS_ORG_LEVEL_ID NUMBER(3,0) NOT NULL 6 .000087 6

  STATE VARCHAR2(3) NOT NULL 2 .000087 2

  STATE_DATE DATE 1,624 .001434 200

  BSS_ORG_CODE VARCHAR2(15) 5,639 .000179 200

  Table Number Empty Average Chain Average Global

  Name of Rows Blocks Blocks Space Count Row Len Stats

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

  BSS_ORG 5,739 52 0 0 0 53 YES

  Column Column Distinct Number

  Name Details Values Density Buckets

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

  BSS_ORG_ID NUMBER(9,0) NOT NULL 5,739 .000174 1

  NAME VARCHAR2(64) NOT NULL 5,034 .000361 200

  BSS_PARENT_ORG_ID NUMBER(9,0) 905 .002189 200

  BSS_ORG_LEVEL_ID NUMBER(3,0) NOT NULL 6 .000087 6

  STATE VARCHAR2(3) NOT NULL 2 .000087 2

  STATE_DATE DATE 1,624 .001434 200

  BSS_ORG_CODE VARCHAR2(15) 5,639 .000179 200
  这里在BSS_PARENT_ORG_ID列上建一个索引,是为了使执行计划与9i、10g下的一致。

  这2条SQL返回的结果行数,与前面的2条SQL一样,分别是5739和4,但是从执行计划上看,Oracle优化器评估出来的行数都是6。

(责任编辑:admin)

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