0

下面是我的查询,我使用四个连接来访问来自三个不同表的数据,现在在搜索 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(易于阅读)

4

3 回答 3

1

如果您要运行数百万行,则基于 100,000 行的测试没有意义。优化器知道,当它通过使用嵌套循环连接有停止键时,它可以更快地满足查询。

当您为一个非常大的数据集运行它时,您可能需要一个不同的计划,最有可能使用散列连接。覆盖索引可能对此有所帮助,但我们无法判断,因为所选列缺少列别名,这些别名告诉我们它们来自哪个表。您最有可能遇到大哈希连接的内存问题,这可以通过哈希分区得到改善,但 Siebel 的人不会这样做——您必须使用手动内存管理并监控 v$sql_workarea 才能看到你真的需要多少。

(顺便说一句,讨厌视觉解释计划)。

于 2013-08-13T11:40:58.083 回答
0

首先,你能确保 S_CONTACT 表上有一个索引并且它是启用的吗?

如果是这样,请尝试带有 /*+ CHOOSE */ 提示的 select 语句,并再次查看说明计划,看看优化器模式是否仍然是 RULE。我相信基于成本的优化器会在这个查询中产生更好的结果。

如果仍然规则,请尝试更新数据库统计信息并重试。您可以为此目的使用 DBMS_STATS 包,如果我没记错的话,它是在 8i 版中引入的。你用的是8i吗?

最后,我不知道记录数,表之间的基数。如果我知道设计,我可能会更有帮助。

于 2013-08-13T10:52:36.517 回答
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

应该改进但不是非常快。

于 2013-08-13T11:25:36.217 回答