oracle 递归查询问题 oracle 自带的递归查询功能:就是点父节点查询所有子节点要是数据量大的话效率会很慢各位有跟好的方法吗 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 看你具体需求是什么了.不过递归sql已经是比较好的选择了 比如说表结构:id name pid1 爷爷 2 爸爸 13 儿子 2类似的,但数据量比较大,用sql递归如:select * from 表 start with id =0 connect by prior id = pid上万条的时候就很慢了 ORACLE既然做出connect by层次化查询来供用户使用应该已经够快了吧想不到什么更高效的办法了 在id 和pid建立索引,并分析执行计划,看查询是否走了索引。这样会提高查询速度。 楼主说得没错,递归的确很慢,而且楼主是只有一万就开始慢了。我遇到20万的,那慢得相当吓人了,其实ORACLE递归如果向上递归是没有问题的,即使500万也没有问题(我们做过这样数据量的测试),因为向上递归都是每次唯一性索引,最多根据层数做不同次数的唯一性索引,这也是很快的。但是向下递归呢,肯定不行了,向下递归因为是根据当前的节点编号去查找是否有相同的PARENT_ID编号,会找到很多,而且下一轮是将这每一个PARENT_ID再看有没有PARENT_ID有没有,全部存入缓存,肯定会装不下,就开始用临时表空间,就更慢了,而且这个算法很显然是很不乐观的,其实学过递归算法的人都知道递归算法是即消耗时间又消耗空间的。那么向下递归是否有办法解决,可以,楼主是否可以尝试一下我的办法,我们测试过上十万的数据向下递归,效果还不错,存储结构上我们增加了一个字段(仅仅限于向下查询,向上查询不行,向上查询继续使用ORACLE提供的递归算法):NODE_ID PARENT_ID ALL_PARENT_ID001 NULL {001}002 001 {001}{002}003 001 {001}{003}004 002 {001}{002}{004}005 002 {001}{002}{005}006 003 {001}{003}{006}.......可以看出ALL_PARENT_ID是等价于本身带一个括号加上PARENT_ID加上一个括号(根节点除外),其实写程序也是蛮好写的。那么如何提高速度呢,你可以看出ALL_PARENT_ID肯定是唯一的,只是把它变成了前缀表达式,加括号的原因是因为怕出现数据前缀的情况,你可以用自己的分隔符号。那么你在这个字段上创建一个唯一性索引。好,ORACLE的规则有一个就是前缀LIKE法则,前缀LIKE法则,ORACLE会走高效的INDEX RANGE SCAN,即高效的查询(LIKE其实并不慢,关键看你如何使用),记得查询前分析下表和索引信息,便于得到正确的执行计划,此时,如你输入一个002,你要查询它的所有子节点,那么就这样使用:如果你要找002的所有子节点,那么就将002的ALL_PARENT_ID字段带进去“{001}{002}”(前台就可以隐藏的带进去),那么此时就只需要用:SELECT * FROM ...WHERE ALL_PARENT_ID LIKE ?||'%';也就是需要匹配出 以“{001}{002}”为前缀的所有节点,通过结构可以看出他们的确是002的所有子节点,并且可以按照ALL_PARENT_ID进行排序,排序后的结果完全是树结构的一个顺序展现。 这个是设计问题,如果一个表的数据有上万条,就不适合做成递归形式了,树状的结构要求数据量不能太多,否则肯定影响速度,如果你实在是没办法,那么就需要自己优化表结构,比如类似SQLSERVER2008中的就有那么一种数据类型叫hierarchyid,可以通过该列的数据直接计算出该行所在数据位于哪个树枝上的哪个节点,Oracle中没有这种数据类型,这就需要自己写算法了。 关于win2008 server的ODBC设置 求Oracle定义anycusor的包PKdual oracle数据库在哪里建表,哪里修改表? imp和exp都很慢,求教 如何将TimesTen数据库一次性导出? EXP-00056: 遇到 ORACLE 错误 1466 col ** format a10 是什么意思啊?具体是实现什么功能的 怎样测低删除一个用户的所有对象? TNS:no listener 初次使用sql*loader出错,请教!在线等待 今天取DMP文件时遇到一个不会解决的问题,大家帮我看看什么会事。 Oracle如何重建表空间
比如说表结构:
id name pid
1 爷爷
2 爸爸 1
3 儿子 2类似的,但数据量比较大,用sql递归如:
select * from 表 start with id =0 connect by prior id = pid上万条的时候就很慢了
应该已经够快了吧想不到什么更高效的办法了
NODE_ID PARENT_ID ALL_PARENT_ID
001 NULL {001}
002 001 {001}{002}
003 001 {001}{003}
004 002 {001}{002}{004}
005 002 {001}{002}{005}
006 003 {001}{003}{006}
.......可以看出ALL_PARENT_ID是等价于本身带一个括号加上PARENT_ID加上一个括号(根节点除外),其实写程序也是蛮好写的。
那么如何提高速度呢,你可以看出ALL_PARENT_ID肯定是唯一的,只是把它变成了前缀表达式,加括号的原因是因为怕出现数据前缀的情况,你可以用自己的分隔符号。那么你在这个字段上创建一个唯一性索引。
好,ORACLE的规则有一个就是前缀LIKE法则,前缀LIKE法则,ORACLE会走高效的INDEX RANGE SCAN,即高效的查询(LIKE其实并不慢,关键看你如何使用),记得查询前分析下表和索引信息,便于得到正确的执行计划,此时,如你输入一个002,你要查询它的所有子节点,那么就这样使用:
如果你要找002的所有子节点,那么就将002的ALL_PARENT_ID字段带进去“{001}{002}”(前台就可以隐藏的带进去),那么此时就只需要用:SELECT * FROM ...
WHERE ALL_PARENT_ID LIKE ?||'%';也就是需要匹配出 以“{001}{002}”为前缀的所有节点,通过结构可以看出他们的确是002的所有子节点,并且可以按照ALL_PARENT_ID进行排序,排序后的结果完全是树结构的一个顺序展现。