如何并行执行Oracle Java存储过程

4

我有一个类似这样的查询:

select samplePackage.prepareMessage(t.message) as text 
from 
sampleSchema.sampleTable t;

sampleTable有大量数据(行数为30M)。 prepareMessage是一个Java存储过程。

private static String prepareMessage(String message) {
   //do some things...
   return preparedMessage;
}

我想要并行执行这个查询,应该怎么做?

谢谢。


2
尝试在select之后添加/*+ PARALLEL */,然后检查查询计划。 - Kevin Burton
3个回答

4
我从未尝试过使用Java函数。但是,应该按照以下步骤进行:

使用PARALLEL提示运行查询:

select /*+ PARALLEL(t) */ samplePackage.prepareMessage(t.message) as text 
from sampleSchema.sampleTable t;

为了成功地并行执行 SELECT 语句,Oracle 需要知道您的 Java 函数是否适合此操作。因此,您需要将其声明为 PARALLEL_ENABLE 或提供 RESTRICT_REFERENCES。
CREATE OR REPLACE FUNCTION PREPARE_MESSAGE(message IN VARCHAR2) RETURN VARCHAR2 PARALLEL_ENABLE
AS LANGUAGE JAVA
    NAME 'sampleSchema.samplePackage.prepareMessage(Java.lang.String) return Java.lang.String';

查询变成了:
select /*+ PARALLEL(t) */ PREPARE_MESSAGE(t.message) as text 
from sampleSchema.sampleTable t;

该函数存在进一步的限制,例如不允许执行DML语句。否则,无法进行并行执行。

正如我所说:我还没有尝试过在Java中使用它。但这是要走的方向。

更新:我已经将代码从包更改为函数。这样应该更简单。


2
使用Oracle预制的API之一,DBMS_JOB包,将多个作业提交到作业队列中,然后并行运行它们。

0

你为什么想要并行处理呢?你打算用结果做什么?

我唯一能想到的并行处理方式就是在一个线程中执行它,然后数据库服务器将返回ResultSet。这个ResultSet可以作为线程的参数,这些线程将检索数据库响应的一部分(例如每个线程将读取1M行)。


我认为你假设 Java 代码执行 SQL 查询,而实际上是反过来的:SELECT 语句调用用 Java 编写的存储过程。Levent Tokmak 没有提到谁运行查询。 - Codo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接