存储结果集以供以后获取

时间:2010-11-07 12:35:25

标签: java sql mysql sql-server oracle

我有一些运行很长时间(20-30分钟)的查询。如果同时启动大量查询,则会快速耗尽连接池。

是否可以将长时间运行的查询包装到一个语句(过程)中,该语句将一般查询的结果存储到临时表中,终止连接,然后根据需要fetchin(轮询)结果?

编辑:查询和数据结构已经过优化,“检查您的指数和执行计划”等提示对我不起作用。我正在寻找一种方法来存储通用结果集的[也许]字节表示,以便稍后进行检索。

4 个答案:

答案 0 :(得分:6)

首先,20-30分钟是查询的长时间 - 您确定没有遗漏查询的任何索引吗?请检查您的执行计划 - 您可以通过良好的索引获得巨大的性能提升。

在MySQL中,你可以做到

INSERT INTO `cached_result_table` (
    SELECT your_query_here
)

(当然,cached_result_table需要与SELECT返回完全相同的列结构,否则会出错。)

然后,您可以查询这些缓存的结果(而不是原始表),并且只是不时运行上述查询 - 更新cached_result_table。

当然,查询最初需要至少运行一次,这需要你提到的20-30分钟。我建议在请求数据之前预先填充缓存表,并保留一些锁定机制以防止更新查询同时运行多次。伪代码:

init:
insert select your_big_query

work:
if your_big_query cached table is empty or nearing expiration:
  refresh in the background:
     check flag to see if there's another "refresh" process running
     if yes
       end // don't run two your_big_queries at the same time
     else 
       set flag
       re-run your_big_query, save to cached table
       clear flag
serve data to clients always from cached table

答案 1 :(得分:2)

在Oracle中,一种简单的方法是“CREATE TABLE sometempname AS SELECT ...”。这将使用select中的结果列创建一个新表。

答案 2 :(得分:1)

不太确定你要求的是什么。

目前您有50个数据库会话。假设您有40个运行长时间运行的查询,剩下10个用于服务其余查询。

您似乎要求的是,您希望那些异步(在后台运行)的40个查询不会堵塞50的连接池。问题是,您是否希望这些40与(可能)另外50个同时运行来自连接池的查询,或者您是否希望它们以某种方式排队?

可以完成排队(查看DBMS_SCHEDULER和DBMS_JOB)。但是您需要将这些结果提供给其他表并知道如何提供该结果集。老式的方法就是根据请求生成报告,将报告传送到共享驱动器上的目录或通过电子邮件发送。可以是PDF或CSV或Excel。

如果您希望40与50'连接池'设置同时运行,那么您可能最好为长时间运行的查询设置单独的连接池。

您可以查看资源管理器以终止占用时间过长或资源过多的调用。这样,在长时间运行的请求中,快速池不会陷入困境。

答案 3 :(得分:0)

我能想到的Oracle中最通用的方法是创建一个存储过程,将结果集转换为XML,并将其作为CLOB XMLType存储在一个表中,其中包含长时间运行的查询的结果。

您可以从通用结果集here中找到有关生成XML的更多信息。

SQL> select dbms_xmlgen.getxml('select employee_id, first_name,
  2  last_name, phone_number from employees where rownum < 6') xml
  3  from dual