H6: migration 006 replaces v_feed's double LEFT JOIN + COUNT(DISTINCT) (which materialized a likes×comments Cartesian per upload) with correlated scalar subqueries that each use their own index. Output columns are unchanged, so feed + hashtag-filtered paths both benefit. H7: feed_delta now applies the feed rate limit (keyed per user), caps results at 200 rows, and clamps how far back a client `since` may reach (7 days). When clamped or capped it returns reload_required=true; the SSE client turns that into a full feed reload instead of streaming the whole gallery through the view on every tab refocus. M9: the SSE reconnect cursor is now advanced only from server timestamps (an upload's created_at, seeded from the feed and updated on new-upload events and delta responses), never the client clock — so a skewed phone clock can't drop events missed while backgrounded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
27 lines
956 B
SQL
27 lines
956 B
SQL
-- H6: replace v_feed's double LEFT JOIN + COUNT(DISTINCT) (which materializes a
|
||
-- likes×comments Cartesian per upload before de-duping) with correlated scalar
|
||
-- subqueries. Each count now uses its own index (idx_like_upload /
|
||
-- idx_comment_upload) and there is no GROUP BY. The output columns are
|
||
-- unchanged, so every consumer keeps working.
|
||
CREATE OR REPLACE VIEW v_feed AS
|
||
SELECT
|
||
u.id,
|
||
u.event_id,
|
||
u.user_id,
|
||
usr.display_name AS uploader_name,
|
||
usr.is_banned,
|
||
usr.uploads_hidden,
|
||
u.preview_path,
|
||
u.thumbnail_path,
|
||
u.mime_type,
|
||
u.caption,
|
||
u.created_at,
|
||
(SELECT COUNT(*) FROM "like" l
|
||
WHERE l.upload_id = u.id) AS like_count,
|
||
(SELECT COUNT(*) FROM comment c
|
||
WHERE c.upload_id = u.id AND c.deleted_at IS NULL) AS comment_count
|
||
FROM upload u
|
||
JOIN "user" usr ON u.user_id = usr.id
|
||
WHERE u.deleted_at IS NULL
|
||
AND usr.uploads_hidden = FALSE;
|