Currently Listening and Pinned start from the person's own rows (#249)
coalesce(s.position, 0) > 5 and coalesce(s.flagged, false) hid from Postgres that a match needs a row of entry_state, so it kept the outer join and scanned every item: Currently Listening read all 574,000 (74,733 blocks from disk), 970 ms of its 1.3 s. s.position > 5 and s.flagged mean the same, a missing row being neither, and let it start from the person's own rows: 2.2 ms, and Pinned 32 ms to 2.3 (EXPLAIN ANALYZE, BUFFERS on production, read only). Unread keeps its coalesce: no row is unread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1219,14 +1219,18 @@ impl Filter {
|
||||
// true and false, not 1 and 0: the columns are booleans on Postgres, and SQLite
|
||||
// reads true and false as 1 and 0.
|
||||
Self::All => "true",
|
||||
// An item with no row of state is unread, so this one keeps its coalesce.
|
||||
Self::Unread => "NOT coalesce(s.read, false)",
|
||||
Self::Flagged => "coalesce(s.flagged, false)",
|
||||
// Pinned and in progress need a row of state, said without coalesce so the database
|
||||
// can tell, and starts from this person's few rows instead of every item: Currently
|
||||
// Listening read all 574,000, 970 ms, where this takes 2 (#249).
|
||||
Self::Flagged => "s.flagged",
|
||||
Self::Downloaded => {
|
||||
"EXISTS (SELECT 1 FROM enclosures x
|
||||
WHERE x.feed_id = e.feed_id AND x.guid = e.guid AND x.path IS NOT NULL)"
|
||||
}
|
||||
Self::InProgress => {
|
||||
"coalesce(s.position, 0) > 5
|
||||
"s.position > 5
|
||||
AND (coalesce(s.duration, e.duration, 0) = 0
|
||||
OR s.position * 10 < coalesce(s.duration, e.duration) * 9)"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user