【发布时间】:2020-02-14 16:19:17
【问题描述】:
我们有一个用于选择一百万条记录的存储过程。存储过程如下所示
CREATE PROCEDURE ABC(@CustID varchar(20))
AS
BEGIN
WITH temporaryTable as (SELECT ab,bc,... FROM Table); // a very huge select query
SELECT a,b, ..., l FROM temporaryTable OUTER JOIN(some_table1)... union all SELECT m,n,..., z FROM temporaryTable OUTER JOIN(some_table2); // two very huge select query with union
END
我的任务是使用该存储过程获取结果,并使用 java 和 spring boot 将其写入 CSV 文件。
我已经尝试了 spring-data-jpa 的 @NamedStoredProcedureQuery 方法来获取结果并使用 opencsv 将其写入 CSV,但这太慢了。我确实使用了 setFirstResult() 和 setMaxResult() 方法,但看不到任何区别(也许这需要以不同方式配置存储过程,但不确定。) p>
现在我正在尝试使用 Spring Batch 的 StoredProcedureItemReader(仍在配置...)读取数据并使用 FlatFileItemWriter 写入 CSV,但我是新手虽然我认为这个链接(https://docs.spring.io/spring-batch/4.1.x/reference/html/scalability.html#scalability)可能会有所帮助,但不确定这是否会有所帮助。
我需要的是一个可以得到想要的结果的方向。
感谢并一如既往地感谢社区提供的任何有用的姿态!!!
【问题讨论】:
-
必须使用存储过程吗?如果没有,您可以将数据复制到临时表并使用 Spring Boot Batch 的任务执行器(多线程)进行块基处理?
-
我会对其进行重组,以便您的联合与临时表的连接分开发生。它会给你带来一个小小的性能提升(我的执行计划显示大约 8%)因为你正在寻找创建一个 csv,我会使用 BCP 和 powershell over Java 和 Spring 来做到这一点。 SELECT a,b FROM temporaryTable tt JOIN( SELECT a,b ... FROM some_table1 UNION ALL SELECT a,b ... FROM some_table2 ) st ON tt.a = st.a AND tt.b = st.b
-
@dbbri - 我会向 DBA 尝试您的建议。至于 BCP 和 powershell 选项,我确实看过它,但它可能不适用于我的情况,因为程序预期用户将能够将程序下载为 ..exe 文件,然后在本地运行。
-
@TechGuy - 是的,我必须使用存储过程。如果我将数据复制到临时表中,这不会增加时间吗?在 Job 中使用基于块的处理和多线程 taskExecutor 的 Step 是我探索 Spring Batch 的兴趣所在,但直到现在我能够获得所需的结果。
-
复制数据不会花费太多时间。您应该尝试这种方法。
标签: java sql-server spring-boot stored-procedures spring-batch