Skip to content

Commit

Permalink
Issue #91: Optimized the top-searches query.
Browse files Browse the repository at this point in the history
  • Loading branch information
haumacher committed Nov 30, 2024
1 parent dd0cbac commit 8edadee
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 27 deletions.
45 changes: 18 additions & 27 deletions phoneblock/src/main/java/de/haumacher/phoneblock/db/DB.java
Original file line number Diff line number Diff line change
Expand Up @@ -658,11 +658,11 @@ public List<? extends SearchInfo> getTopSearches(int limit) {
int lastRev = nonNull(reports.getLastRevision());

int baseRev = lastRev > 0 ? lastRev - 1 : 0;
long revisionDate = orMidnightYesterday(reports.getRevisionDate(baseRev));
long revTime = orMidnightYesterday(reports.getRevisionDate(baseRev));

if (false) {
// Note: This query produces nonsense results when fired through ibatis. The conventional way below works as expected.
List<DBSearchInfo> result = reports.getTopSearches(lastRev, revisionDate, limit);
List<DBSearchInfo> result = reports.getTopSearches(lastRev, revTime, limit);
result.sort((a,b)->-Integer.compare(a.getCount(), b.getCount()));

result = result.subList(0, limit);
Expand All @@ -672,34 +672,25 @@ public List<? extends SearchInfo> getTopSearches(int limit) {

return result;
} else {
Connection connection = session.getConnection();
try (PreparedStatement stmt = connection.prepareStatement(
"""
select s.PHONE, s.SEARCHES - COALESCE(h.SEARCHES, 0) CNT, s.SEARCHES TOTAL, s.UPDATED from NUMBERS s
left outer join NUMBERS_HISTORY h on h.PHONE = s.PHONE and h.RMIN <= ? and h.RMAX >= ?
where s.UPDATED > ?
order by CNT desc
""")) {

stmt.setInt(1, baseRev);
stmt.setInt(2, baseRev);
stmt.setLong(3, revisionDate);

List<DBSearchInfo> result = new ArrayList<>();
try (ResultSet res = stmt.executeQuery()) {
while (res.next() && result.size() < limit) {
result.add(new DBSearchInfo(res.getString(1), res.getInt(2), res.getInt(3), res.getLong(4)));
}
List<DBSearchInfo> searches = reports.getSearchesSince(revTime);
Set<String> numbers = searches.stream().map(s -> s.getPhone()).collect(Collectors.toSet());
Map<String, DBSearchInfo> atRev = reports.getSearchesAt(baseRev, numbers).stream().collect(Collectors.toMap(s -> s.getPhone(), s -> s));

for (DBSearchInfo s : searches) {
DBSearchInfo base = atRev.get(s.getPhone());
if (base == null) {
s.setCount(s.getTotal());
} else {
s.setCount(s.getTotal() - base.getTotal());
}

// Bring in last search order.
result.sort((a,b)->-Long.compare(a.getLastSearch(), b.getLastSearch()));

return result;
}

searches.sort(Comparator.<DBSearchInfo>comparingInt(s -> s.getCount()).reversed());
searches = searches.subList(0, limit);

searches.sort(Comparator.<DBSearchInfo>comparingLong(s -> s.getLastSearch()).reversed());
return searches;
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,24 @@ SELECT COUNT(1) FROM NUMBERS s
""")
List<DBSearchInfo> getTopSearches(int rev, long revTime, int limit);

@Select("""
select s.PHONE, 0, s.SEARCHES TOTAL, s.UPDATED from NUMBERS s
where s.UPDATED > #{revTime}
""")
List<DBSearchInfo> getSearchesSince(long revTime);

@Select("""
<script>
select h.PHONE, 0, h.SEARCHES TOTAL, 0 from NUMBERS_HISTORY h
where h.PHONE in
<foreach item="item" index="index" collection="numbers" open="(" separator="," close=")">
#{item}
</foreach>
and h.RMIN &lt;= ${rev} and h.RMAX &gt;= ${rev}
</script>
""")
List<DBSearchInfo> getSearchesAt(int rev, Set<String> numbers);

/**
* Retrieves all historic versions for the given number not older than the given revision.
*
Expand Down

0 comments on commit 8edadee

Please sign in to comment.