提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2009-11-19 10:23:06.000|阅读 845 次
概述:Oracle提供了方便的树形查询功能,也就是connect by 语句。树形结构是很常见的,比如组织机构树,产品目录树等。本文不讲述connect by 如何使用,只是提出在使用树形查询时需要考虑的一个有关于性能方面的问题。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
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。
从前面的两个测试来看,优化器评估出来的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了。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:网络转载面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢