【发布时间】:2020-12-27 00:02:23
【问题描述】:
我有一个 Spring 批处理,每天都会运行到:
-
读取 CSV 文件并将其导入我们的数据库
-
聚合这些数据并将这些聚合数据保存到另一个表中。
我们有一个表BATCH_LIST,其中包含有关已执行的所有批次的信息。
BATCH_LIST 具有以下列:
1. BATCH_ID
2. EXECUTION_DATE
3. STATUS
在导入的 CSV 文件中,我们有一个 CSV 文件用于提供APP_USERS 表,另一个用于提供ACCOUNTS 表。
APP_USERS 具有以下列:
1. USER_ID
2. BATCH_ID
-- more columns
ACCOUNTS 具有以下列:
1. ACCOUNT_ID
2. BATCH_ID
-- more columns
在第 2 步中,我们聚合来自 ACCOUNTS 和 APP_USERS 的数据,以将行插入到 USER_ACCOUNT_RELATION 表中。该表正好有两列:ACCOUNT_ID(参考ACCOUNTS.ACCOUNT_ID)和USER_ID(参考APP_USERS.USER_ID)。
现在我们想在 Spring 批处理中添加另一个步骤。我们要删除USER_ACCOUNT_RELATION 表中的所有数据,以及不再相关的APP_USERS 和ACCOUNTS(即在sysdate - 2 之前导入的数据。
到目前为止做了什么:
-
获取我们要从数据库中删除的所有
BATCH_IDSELECT BATCH_ID FROM BATCH_LIST WHERE trunc(EXECUTION_DATE) < sysdate - 2 -
对于每个
BATCH_ID,我们调用以下方法:public void deleteAppUsersByBatchId(Connection connection, long batchId) throws SQLException // prepared statements to delete User account relation and user
这是两个准备好的语句:
DELETE FROM USER_ACCOUNT_RELATION
WHERE USER_ID IN (
SELECT USER_ID FROM APP_USERS WHERE BATCH_ID = ?
);
DELETE FROM APP_USERS WHERE BATCH_ID = ?
我的问题是删除一个 BATCH_ID 的数据需要很长时间(超过 1 小时)。
注意:我只提到了APP_USERS、ACCOUNTS 和USER_ACCOUNT_RELATION 表,但实际上我有大约 25 个表要删除。
如何提高查询时间?
(我刚刚尝试将WHERE USER_ID IN () 更改为EXISTS。它更好但仍然太长了。
【问题讨论】:
-
你有多少个XX?你从哪里得到它们?
-
现在,我有 70 个。每天,我们都会收到导入数据库的文件。在生产环境中,我不会像在测试环境中那样拥有那么多的 FILE_ID。
-
在 FILE_ID 上为 USER 和 ACCOUNT 添加索引。
-
非常感谢。一开始我想这样做(这就是我在索引上添加注释的原因),但我在某处读到,你拥有的索引越多,删除的速度就越慢。
-
你有分区选项吗?删除数据最简单的方法是删除整个分区
标签: sql database oracle performance