2

我在 Oracle 10g 中有一个 INSERT 查询,它卡在“来自 dblink 的 SQL*Net 消息”事件上。看起来像:

INSERT INTO my_table (A, B, C, ...) 
  SELECT A, B, C, ... FROM link_table@other_system;

my_table除了我正在尝试执行的 INSERT 中的锁之外,我没有看到任何锁。单独运行时,SELECT 查询可以link_table@other_system毫无问题地完成。我只有在尝试进行 INSERT 时才会遇到这个问题。

有谁知道这里会发生什么?

更新 SELECT 在单独运行时在约 1.5 分钟内返回 4857 行。在我决定杀死它之前,INSERT 运行了一个多小时,并带有这个等待消息。

更新 我在我的方法中发现了一个错误。我使用日期范围来限制结果。我仅在测试 SELECT 时使用的日期范围是在最后一次在 link_table 上运行 OraStats 之前,但我在测试 INSERT 时使用的日期范围是在最后一次在 link_table 上运行 OraStats 之后。所以,这误导我相信 INSERT 有问题。我这样做不是很科学;我的错。

4

2 回答 2

2

SQL*Net message from dblink通常意味着您的本地系统正在网络上等待通过网络传输数据。对于此类查询,这是一个非常正常的等待事件。

SELECT语句返回多少行?这代表了多少数据(以 MB/GB 为单位)?

当您说它“自行完成而没有任何麻烦”时,您实际上是在获取所有数据吗?如果您使用的是 TOAD 或 SQL Developer 之类的东西,GUI 通常会获取前 N 行并返回给您。这可能非常快,但并不意味着数据库已完成执行查询 - 完成生成查询将返回的所有行可能需要更多时间。人们通常测量获取前 N 行所需的时间而不是获取最后一行的时间——显然,在从远程表中获取所有行之前,您的 INSERT 语句无法返回。

于 2012-06-20T19:54:28.513 回答
2

您是否使用/*+ driving_site(link_table) */提示让 Oracle 在远程服务器上执行连接?

If so, that hint will not work with DML, as explained by Jonathan Lewis on this page.

This may be a rare case where running the query just as a SELECT uses a very different plan than running the query as part of an INSERT. (You will definitely want to learn how to generate explain plans in your environment. Most tools have a button to do this.)

As Andras Gabor recommended in the link, you may want to use PL/SQL BULK COLLECT to improve performance. This may be a rare case where PL/SQL will work faster than SQL.

于 2012-06-22T04:42:13.890 回答