Oracle 10g Connect By Prior - 性能问题
我有以下 SQL 语句:
SELECT
CONNECT_BY_ROOT ANIMAL_ID "ORIGINAL_ANIMAL" ,
ANIMAL_ID, LINE_ID, SIRE_ANIMAL_ID, DAM_ANIMAL_ID,
LEVEL -1 "LEVEL" FROM ANIMALS
START WITH ANIMAL_ID IN( '2360000002558' )
CONNECT BY
((PRIOR SIRE_ANIMAL_ID = ANIMAL_ID and LEVEL < 5) OR (PRIOR DAM_ANIMAL_ID = ANIMAL_ID AND LEVEL < 5))
这是在一个包含大约 160 万只动物的表中。每条记录都有 Animal_Id、Sire_Animal_Id 和 Dam_Animal_Id(Sire = 父亲,Dam = 母亲)。
我使用这个 sql 来显示完整的动物谱系。结果将显示动物、2 个父母、4 个祖父母等。
我的问题是,对于一只动物,此语句需要 15 秒。必须有一种方法来优化这一点。有什么想法吗?
I have the following SQL statement:
SELECT
CONNECT_BY_ROOT ANIMAL_ID "ORIGINAL_ANIMAL" ,
ANIMAL_ID, LINE_ID, SIRE_ANIMAL_ID, DAM_ANIMAL_ID,
LEVEL -1 "LEVEL" FROM ANIMALS
START WITH ANIMAL_ID IN( '2360000002558' )
CONNECT BY
((PRIOR SIRE_ANIMAL_ID = ANIMAL_ID and LEVEL < 5) OR (PRIOR DAM_ANIMAL_ID = ANIMAL_ID AND LEVEL < 5))
This in in a table with about 1.6 Million animals. Each record has Animal_Id, Sire_Animal_Id, and Dam_Animal_Id (Sire = Father, Dam = Mother).
I use this sql to display the full animal pedigree. Results Will show Animal, 2 Parent, 4 GrandParents, etc.
My issue is that this statement takes 15 seconds, for one animal. There has got to be a way to optimize this. Any thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我尝试重现您的情况,但无法让 Oracle 明智地使用索引。我确信有一些聪明的方法可以做到这一点。但如果这里没有其他人能弄清楚的话,下面是一种愚蠢、丑陋的方法。
由于您只能获得一定数量的级别,因此您可以手动创建连接。获取第一级,将其联合到第二级(从第一个查询的副本获取结果),将其联合到第三级(从第二个查询的副本获取结果),等等。我只做了三个级别在这里,但您可以复制并粘贴以制作第四个。由于原始 id 重复了很多次,所以使用起来比较困难,但它非常快(在我的机器上有 160 万条记录,只用了 0.005 秒。)
I tried recreating your situation and I wasn't able to get Oracle to use the indexes wisely. I'm sure there's some smart way to do it. But if no one else here can figure it out, below is the dumb, ugly way.
Since you're only getting a certain number of levels you can manually create a connect by. Get the first level, union that to the second level (which gets results from a copy of the first query), union that to the third level (which gets results from a copy of the second query), etc. I only did three levels here, but you can copy and paste to make the fourth. It's harder to use since the original id is repeated so many times, but it's super fast (0.005 seconds on my machine with 1.6 million records.)
我没有很长时间来测试这个,所以答案中有一点 DYOR,但是使用内联视图有帮助吗?
由于您还没有发布解释计划,我恐怕无法提供太多帮助,在下面的解决方案中,您可能会发现WITH子句中的联合会导致性能问题,但它可能会帮助您解决问题解决方案。
I haven't had a long time to test this so there is a bit of DYOR in the answer but would using an inline view help?
As you haven't posted an explain plan I can't help too much i'm afraid and in the solution below, you may find that the union in the WITH clause causes you performance issues but it might help you on your way to a solution.