perf(dashboard): economy reports on a large ledger

- Leave staff out of the currency and U-score reports by excluding the few staff characters,
  instead of joining every ledger row to its character and account.
- Top earners: total per character first and look up names for the top rows only.
- The places list and the activity report read map events for every kind in one query
  (GetMapZonesAllKinds) instead of one query per kind.

With about 1M currency rows and 650k map event rows (90 days) on MariaDB: currency 1.8 s to
0.8 s, top earners 2.4 s to 0.75 s, places 2.6 s to 0.5 s, activity 2.6 s to 1.7 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-26 18:55:03 -05:00
parent 98fd72cf75
commit fa3e5de1d9
9 changed files with 45 additions and 15 deletions

View File

@@ -258,6 +258,7 @@ public:
uint32_t GetMaxBugReportId() override;
nlohmann::json GetTransfersForCharacters(const std::vector<LWOOBJID>& characterIds, uint32_t start, uint32_t length) override;
nlohmann::json GetMapZones(eMapEvent kind, uint32_t fromDay, uint32_t toDay) override;
nlohmann::json GetMapZonesAllKinds(uint32_t fromDay, uint32_t toDay) override;
nlohmann::json GetMapLots(uint32_t zone, std::optional<uint32_t> clone, eMapEvent kind, uint32_t fromDay, uint32_t toDay, uint32_t limit) override;
nlohmann::json GetMapCells(uint32_t zone, std::optional<uint32_t> clone, eMapEvent kind, uint32_t fromDay, uint32_t toDay, LOT lot) override;
nlohmann::json GetMapEventsPerDay(uint32_t fromDay, uint32_t toDay, const PlaceFilter& place) override;

View File

@@ -214,6 +214,17 @@ nlohmann::json SQLiteDatabase::GetMapZones(eMapEvent kind, uint32_t fromDay, uin
return rows;
}
nlohmann::json SQLiteDatabase::GetMapZonesAllKinds(uint32_t fromDay, uint32_t toDay) {
auto [_, result] = ExecuteSelect("SELECT kind, zone, clone_id, SUM(events) AS events, SUM(quantity) AS quantity FROM map_events_daily "
"WHERE day BETWEEN ? AND ? GROUP BY kind, zone, clone_id ORDER BY kind, events DESC, zone, clone_id;", fromDay, toDay);
nlohmann::json rows = nlohmann::json::array();
for (; !result.eof(); result.nextRow()) {
rows.push_back({ {"kind", result.getIntField("kind")}, {"zone", result.getIntField("zone")}, {"clone", static_cast<uint32_t>(result.getInt64Field("clone_id"))},
{"events", result.getInt64Field("events")}, {"quantity", result.getInt64Field("quantity")} });
}
return rows;
}
nlohmann::json SQLiteDatabase::GetMapLots(uint32_t zone, std::optional<uint32_t> clone, eMapEvent kind, uint32_t fromDay, uint32_t toDay, uint32_t limit) {
auto [_, result] = ExecuteSelect("SELECT lot, SUM(events) AS events, SUM(quantity) AS quantity FROM map_events_daily "
"WHERE zone = ? AND kind = ? AND day BETWEEN ? AND ?" + CloneSql(clone) + " GROUP BY lot ORDER BY events DESC, lot LIMIT ?;", zone, static_cast<uint32_t>(kind), fromDay, toDay, limit);