下面是我的查询,我使用四个连接来访问来自三个不同表的数据,现在当搜索1000个记录时需要大约5.5秒,但是当我将其放大到100,000时,它需要看起来无限的时间,(最后7小时取消..)
有没有人知道我做错了什么?或者可以采取哪些措施来加速查询?
这个查询可能最终必须运行才能返回数百万条记录,为了测试查询,我只将其限制在100,000条,而且即使只是这么小的数量,它也似乎有所下降。
对于oracle 8上的记录
CREATE TABLE co_tenancyind_batch01 AS
SELECT /*+ CHOOSE */ ou_num,
x_addr_relat,
x_mastership_flag,
x_ten_3rd_party_source
FROM s_org_ext,
s_con_addr,
s_per_org_unit,
s_contact
WHERE s_org_ext.row_id = s_con_addr.accnt_id
AND s_org_ext.row_id = s_per_org_unit.ou_id
AND s_per_org_unit.per_id = s_contact.row_id
AND x_addr_relat IS NOT NULL
AND rownum < 100000
解释图片中的计划:http://imgur.com/Xw9x4BA(易于阅读)
答案 0 :(得分:1)
如果您要运行数百万行,那么基于100,000行的测试没有意义。优化器知道通过使用嵌套循环连接,它可以更快地满足查询。
当你为一个非常大的数据集运行它时,你可能需要一个不同的计划,最有可能使用散列连接。覆盖索引可能对此有所帮助,但我们无法分辨,因为所选列缺少列别名,告诉我们它们来自哪个表。您最有可能遇到大型散列连接的内存问题,这可能会通过散列分区得到改善,但Siebel人员无法实现这一点 - 您必须使用手动内存管理并监视v $ sql_workarea才能看到你真正需要多少。
(顺便讨厌视觉解释计划)。
答案 1 :(得分:0)
首先,您能否确定S_CONTACT表上有索引并且已启用?
如果是这样,请尝试使用/ * + CHOOSE * / hint的select语句,再看看解释计划,看看优化器模式是否仍然是RULE。我相信基于成本的优化器在这个查询中会更好。
如果仍然规则尝试更新数据库统计信息,请重试。你可以使用DBMS_STATS包来实现这个目的,如果我没有错,它是在8i版本中引入的。你在用8i吗?
最后,我不知道记录号码,表格之间的基数。如果我知道设计,我可能会更有帮助。
答案 2 :(得分:0)
您的数据集,查看上一个执行计划似乎很大,您可以限制对基表的访问,而不是限制返回的行数,如下所示:
CREATE TABLE co_tenancyind_batch01 AS
SELECT /*+ CHOOSE */ ou_num,
x_addr_relat,
x_mastership_flag,
x_ten_3rd_party_source
FROM s_org_ext,
s_con_addr,
s_per_org_unit,
(select * from s_contact where rownum <= 100000) cont
WHERE s_org_ext.row_id = s_con_addr.accnt_id
AND s_org_ext.row_id = s_per_org_unit.ou_id
AND s_per_org_unit.per_id = cont.row_id
AND x_addr_relat IS NOT NULL
应该改善但不是非常快。