From 5df78e305e9d48f5b0663a8ddd5d128e3d5d7828 Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Mon, 5 Oct 2026 05:22:48 +0600 Subject: [PATCH] Read the library's last read time without joining history to chapters Migration 18 replaces libraryView, so the version code is bumped. --- app/build.gradle.kts | 2 +- .../sqldelight/tachiyomi/migrations/18.sqm | 59 +++++++++++++++++++ .../sqldelight/tachiyomi/view/libraryView.sq | 24 ++++++-- 3 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 data/src/main/sqldelight/tachiyomi/migrations/18.sqm diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9e7717436..43227e67f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -37,7 +37,7 @@ android { defaultConfig { applicationId = "app.mihon" - versionCode = 34 + versionCode = 35 versionName = "0.20.4" buildConfigField("boolean", "TELEMETRY_INCLUDED", "${Config.includeTelemetry}") diff --git a/data/src/main/sqldelight/tachiyomi/migrations/18.sqm b/data/src/main/sqldelight/tachiyomi/migrations/18.sqm new file mode 100644 index 000000000..e8f40ba46 --- /dev/null +++ b/data/src/main/sqldelight/tachiyomi/migrations/18.sqm @@ -0,0 +1,59 @@ +-- Read the library's last read time from history without joining it to every chapter + +DROP VIEW libraryView; + +CREATE VIEW libraryView AS +SELECT + M.*, + coalesce(C.total, 0) AS totalCount, + coalesce(C.readCount, 0) AS readCount, + coalesce(C.latestUpload, 0) AS latestUpload, + coalesce(C.fetchedAt, 0) AS chapterFetchedAt, + -- Joining history to every chapter is the slowest part of the query, and only entries with excluded + -- scanlators need the chapters to leave theirs out + coalesce( + CASE WHEN EXISTS (SELECT 0 FROM excluded_scanlator WHERE excluded_scanlator.manga_id = M.id) + THEN ( + SELECT max(history.read_at) + FROM history + JOIN chapter + ON chapter.id = history.chapter_id + WHERE history.manga_id = M.id + AND NOT EXISTS ( + SELECT 0 FROM excluded_scanlator + WHERE excluded_scanlator.manga_id = M.id + AND excluded_scanlator.scanlator = chapter.remote_scanlator + ) + ) + ELSE (SELECT max(history.read_at) FROM history WHERE history.manga_id = M.id) + END, + 0 + ) AS lastRead, + coalesce(C.bookmarkCount, 0) AS bookmarkCount, + coalesce(MC.categories, '0') AS categories +FROM manga M +LEFT JOIN ( + SELECT + chapter.manga_id, + count(*) AS total, + sum(user_read) AS readCount, + coalesce(max(chapter.remote_date_upload), 0) AS latestUpload, + coalesce(max(chapter.state_date_fetch), 0) AS fetchedAt, + sum(chapter.user_bookmark) AS bookmarkCount + FROM chapter + LEFT JOIN excluded_scanlator + ON chapter.manga_id = excluded_scanlator.manga_id + AND chapter.remote_scanlator = excluded_scanlator.scanlator + WHERE excluded_scanlator.scanlator IS NULL + AND chapter.manga_id IN (SELECT id FROM manga WHERE user_favorite_at IS NOT NULL) + GROUP BY chapter.manga_id +) AS C +ON M.id = C.manga_id +LEFT JOIN ( + SELECT manga_id, group_concat(category_id) AS categories + FROM manga_category + WHERE manga_id IN (SELECT id FROM manga WHERE user_favorite_at IS NOT NULL) + GROUP BY manga_id +) AS MC +ON MC.manga_id = M.id +WHERE M.user_favorite_at IS NOT NULL; diff --git a/data/src/main/sqldelight/tachiyomi/view/libraryView.sq b/data/src/main/sqldelight/tachiyomi/view/libraryView.sq index 8c76d6adc..5717e3166 100644 --- a/data/src/main/sqldelight/tachiyomi/view/libraryView.sq +++ b/data/src/main/sqldelight/tachiyomi/view/libraryView.sq @@ -5,7 +5,26 @@ SELECT coalesce(C.readCount, 0) AS readCount, coalesce(C.latestUpload, 0) AS latestUpload, coalesce(C.fetchedAt, 0) AS chapterFetchedAt, - coalesce(C.lastRead, 0) AS lastRead, + -- Joining history to every chapter is the slowest part of the query, and only entries with excluded + -- scanlators need the chapters to leave theirs out + coalesce( + CASE WHEN EXISTS (SELECT 0 FROM excluded_scanlator WHERE excluded_scanlator.manga_id = M.id) + THEN ( + SELECT max(history.read_at) + FROM history + JOIN chapter + ON chapter.id = history.chapter_id + WHERE history.manga_id = M.id + AND NOT EXISTS ( + SELECT 0 FROM excluded_scanlator + WHERE excluded_scanlator.manga_id = M.id + AND excluded_scanlator.scanlator = chapter.remote_scanlator + ) + ) + ELSE (SELECT max(history.read_at) FROM history WHERE history.manga_id = M.id) + END, + 0 + ) AS lastRead, coalesce(C.bookmarkCount, 0) AS bookmarkCount, coalesce(MC.categories, '0') AS categories FROM manga M @@ -15,15 +34,12 @@ LEFT JOIN ( count(*) AS total, sum(user_read) AS readCount, coalesce(max(chapter.remote_date_upload), 0) AS latestUpload, - coalesce(max(history.read_at), 0) AS lastRead, coalesce(max(chapter.state_date_fetch), 0) AS fetchedAt, sum(chapter.user_bookmark) AS bookmarkCount FROM chapter LEFT JOIN excluded_scanlator ON chapter.manga_id = excluded_scanlator.manga_id AND chapter.remote_scanlator = excluded_scanlator.scanlator - LEFT JOIN history - ON chapter.id = history.chapter_id WHERE excluded_scanlator.scanlator IS NULL AND chapter.manga_id IN (SELECT id FROM manga WHERE user_favorite_at IS NOT NULL) GROUP BY chapter.manga_id