perf(api): kilka tagow od najnowszych idzie po indeksie najrzadszego z nich
Z dwoma tagami (rough-sex + anal) lista szla stara droga po calym katalogu, 7,4 s na zimnym cache. Teraz dolaczamy najrzadszy tag po ix_scene_tags_tag_sort, a reszta zostaje jako EXISTS: 0,2 s. Dolaczona tabela ma alias, inaczej EXISTS po scene_tags korelowal sie z nia. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
7f2fdfaed0
commit
73853eb9ed
1 changed files with 17 additions and 12 deletions
|
|
@ -466,22 +466,25 @@ def list_scenes(
|
|||
# ix_scenes_created_at_desc zamiast materializować wszystkie scene_tags. Slug-JOIN
|
||||
# ukrywał tag_id przed plannerem → używał średniej (8.4M/11541≈726) → zły plan
|
||||
# (4-12s). Z literałem: ~20ms. Zob. też _build... light mode.
|
||||
# Jeden tag + sort od najnowszych (ekran tagu w apce): zamiast EXISTS dolaczamy wiersz
|
||||
# scene_tags i sortujemy po jego `sort_date`, patrz galaz sort == "release_date".
|
||||
# Sort od najnowszych z filtrem tagu: jeden tag zamiast EXISTS dolaczamy jako wiersz
|
||||
# scene_tags i sortujemy po jego `sort_date` (galaz sort == "release_date"). Przy kilku
|
||||
# tagach dolaczamy NAJRZADSZY, bo spacer po indeksie konczy sie najpozniej na jego
|
||||
# ostatniej scenie; reszta zostaje jako EXISTS. rough-sex + anal: 7,4 s na zimnym cache
|
||||
# po starej sciezce (2026-09-18).
|
||||
tag_sort_id: uuid.UUID | None = None
|
||||
if tag_slug_list:
|
||||
id_by_slug = dict(
|
||||
session.execute(
|
||||
select(Tag.slug, Tag.id).where(Tag.slug.in_(tag_slug_list))
|
||||
).all()
|
||||
)
|
||||
tag_rows = session.execute(
|
||||
select(Tag.slug, Tag.id, Tag.scene_count).where(Tag.slug.in_(tag_slug_list))
|
||||
).all()
|
||||
id_by_slug = {slug: tid for slug, tid, _ in tag_rows}
|
||||
if sort == "release_date" and tag_rows:
|
||||
tag_sort_id = min(tag_rows, key=lambda r: r[2] or 0)[1]
|
||||
for slug in tag_slug_list:
|
||||
tag_id = id_by_slug.get(slug)
|
||||
if tag_id is None:
|
||||
base = base.where(false()) # nieznany slug → brak wyników
|
||||
break
|
||||
if len(tag_slug_list) == 1 and sort == "release_date":
|
||||
tag_sort_id = tag_id
|
||||
if tag_id == tag_sort_id:
|
||||
continue
|
||||
base = base.where(
|
||||
exists(
|
||||
|
|
@ -651,16 +654,18 @@ def list_scenes(
|
|||
# od strefy sesji, stad jawne AT TIME ZONE 'UTC'. Indeks:
|
||||
# ix_scenes_effective_date_desc (migracja 0033).
|
||||
if tag_sort_id is not None:
|
||||
# Z filtrem jednego tagu ta sama data siedzi w scene_tags.sort_date (wyzwalacz,
|
||||
# Z filtrem tagu ta sama data siedzi w scene_tags.sort_date (wyzwalacz,
|
||||
# migracja 0042) i idzie po ix_scene_tags_tag_sort (0043): od najnowszej sceny
|
||||
# tagu, koniec po LIMIT. Po samym `scenes` Postgres sprawdzal tag scena po scenie
|
||||
# od najnowszej w calym katalogu i przy tagach rzedu 40-60 tys. scen (`rough-sex`)
|
||||
# przegladal 46 tys. scen na jedna strone: 7-15 s na zimnym cache (GOON-64).
|
||||
# W obrebie jednego dnia kolejnosc po id, nie po created_at: indeks jest
|
||||
# wezszy, a stronicowanie i tak stabilne.
|
||||
# Alias, bo przy kilku tagach EXISTS po scene_tags skorelowalby sie z tym JOIN-em.
|
||||
st = aliased(SceneTag)
|
||||
ordered = base.join(
|
||||
SceneTag, and_(SceneTag.scene_id == Scene.id, SceneTag.tag_id == tag_sort_id)
|
||||
).order_by(SceneTag.sort_date.desc(), SceneTag.scene_id.desc())
|
||||
st, and_(st.scene_id == Scene.id, st.tag_id == tag_sort_id)
|
||||
).order_by(st.sort_date.desc(), st.scene_id.desc())
|
||||
else:
|
||||
ordered = base.order_by(
|
||||
_effective_date_desc(), Scene.created_at.desc(), Scene.id.desc()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue