From 8749d121284c37c80731a95ce342c3094dc771a6 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 2 Nov 2019 11:35:04 +0200 Subject: [PATCH] Rewrote RemoveDuplicateUserInfoTransaction NOT IN has a long execution time and leads to lock time being large. Modified the transaction to select the duplicates and then remove them Affects issues: - Possibly fixed #1212 --- .../RemoveDuplicateUserInfoTransaction.java | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/init/RemoveDuplicateUserInfoTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/init/RemoveDuplicateUserInfoTransaction.java index cc3b4f391..a1d8d8a53 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/init/RemoveDuplicateUserInfoTransaction.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/init/RemoveDuplicateUserInfoTransaction.java @@ -16,9 +16,18 @@ */ package com.djrapitops.plan.storage.database.transactions.init; +import com.djrapitops.plan.storage.database.queries.QueryAllStatement; import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable; +import com.djrapitops.plan.storage.database.transactions.ExecBatchStatement; import com.djrapitops.plan.storage.database.transactions.ThrowawayTransaction; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + import static com.djrapitops.plan.storage.database.sql.parsing.Sql.*; /** @@ -31,20 +40,40 @@ import static com.djrapitops.plan.storage.database.sql.parsing.Sql.*; */ public class RemoveDuplicateUserInfoTransaction extends ThrowawayTransaction { - private static final String COLUMN_ID = UserInfoTable.TABLE_NAME + '.' + UserInfoTable.ID; private static final String STATEMENT_SELECT_DUPLICATE_IDS = - SELECT + "MIN(" + COLUMN_ID + ") as id" + FROM + UserInfoTable.TABLE_NAME + - GROUP_BY + UserInfoTable.USER_UUID + ',' + UserInfoTable.SERVER_UUID; + SELECT + DISTINCT + "u2." + UserInfoTable.ID + " as id" + + FROM + UserInfoTable.TABLE_NAME + " u1" + + INNER_JOIN + UserInfoTable.TABLE_NAME + " u2 on " + + "u1." + UserInfoTable.USER_UUID + "=u2." + UserInfoTable.USER_UUID + AND + + "u1." + UserInfoTable.SERVER_UUID + "=u2." + UserInfoTable.SERVER_UUID + AND + + "u1." + UserInfoTable.ID + " duplicateIDs = getDuplicates(); + if (duplicateIDs.isEmpty()) return; + + execute(new ExecBatchStatement(DELETE_FROM + UserInfoTable.TABLE_NAME + WHERE + UserInfoTable.ID + "=?") { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + for (Integer id : duplicateIDs) { + statement.setInt(1, id); + statement.addBatch(); + } + } + }); + } + + private Collection getDuplicates() { + return query(new QueryAllStatement>(STATEMENT_SELECT_DUPLICATE_IDS) { + @Override + public Collection processResults(ResultSet set) throws SQLException { + Set duplicateIDs = new HashSet<>(); + while (set.next()) { + duplicateIDs.add(set.getInt("id")); + } + return duplicateIDs; + } + }); } } \ No newline at end of file