mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 03:29:19 +02:00
schema: add composite index (is_published, year DESC) + fix stale migration 005
- Add idx_theses_pub_year composite index on theses(is_published, year DESC) to schema.sql; replaces the need for the query planner to pick between the two separate idx_theses_published / idx_theses_year indexes and sort with a temp B-tree. Every public query filters on is_published=1 and orders/filters by year, so this covering index eliminates the sort pass for those queries. - Create storage/migrations/006_add_composite_index.sql and apply to both posterg.db and test.db. - Fix storage/migrations/005_add_banner.sql: the view recreation in that file still referenced the pre-migration-001 table/column names (thesis_keywords, keywords.keyword). Updated to use thesis_tags / tags tg to match the canonical schema.sql. The live DB was unaffected (migration 001 ran before 005), but the file was misleading and would fail if ever re-run from scratch.
This commit is contained in:
4
TODO.md
4
TODO.md
@@ -351,7 +351,7 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
|||||||
Eliminates full-database read-locks on every write; makes concurrent PHP-FPM workers safe.
|
Eliminates full-database read-locks on every write; makes concurrent PHP-FPM workers safe.
|
||||||
Also add `PRAGMA cache_size = -8000` (≈8 MB page cache) while there.
|
Also add `PRAGMA cache_size = -8000` (≈8 MB page cache) while there.
|
||||||
|
|
||||||
- [ ] **Composite index `(is_published, year DESC)`** on `theses` — every public query filters on both.
|
- [x] **Composite index `(is_published, year DESC)`** on `theses` — every public query filters on both.
|
||||||
Currently `idx_theses_published` and `idx_theses_year` are separate; the query planner picks one
|
Currently `idx_theses_published` and `idx_theses_year` are separate; the query planner picks one
|
||||||
and sorts the other with a temp B-tree. A single covering index eliminates the sort:
|
and sorts the other with a temp B-tree. A single covering index eliminates the sort:
|
||||||
`CREATE INDEX IF NOT EXISTS idx_theses_pub_year ON theses(is_published, year DESC);`
|
`CREATE INDEX IF NOT EXISTS idx_theses_pub_year ON theses(is_published, year DESC);`
|
||||||
@@ -370,7 +370,7 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
|||||||
`Database::getPublishedAuthors(): array` that queries `thesis_authors JOIN authors` directly,
|
`Database::getPublishedAuthors(): array` that queries `thesis_authors JOIN authors` directly,
|
||||||
avoiding the view entirely.
|
avoiding the view entirely.
|
||||||
|
|
||||||
- [ ] **`migration 005` view is stale in the file** — `005_add_banner.sql` recreates the view still
|
- [x] **`migration 005` view is stale in the file** — `005_add_banner.sql` recreates the view still
|
||||||
referencing `thesis_keywords` / `keywords.keyword` (the old pre-migration-001 names).
|
referencing `thesis_keywords` / `keywords.keyword` (the old pre-migration-001 names).
|
||||||
The file is already applied to the live DB (correctly, since 001 ran first), but the migration
|
The file is already applied to the live DB (correctly, since 001 ran first), but the migration
|
||||||
file itself is wrong and misleading. Fix: rewrite it to reference `thesis_tags` / `tags.name`,
|
file itself is wrong and misleading. Fix: rewrite it to reference `thesis_tags` / `tags.name`,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ SELECT
|
|||||||
GROUP_CONCAT(DISTINCT CASE WHEN ts.role = 'lecteur' THEN s.name END) as jury_lecteurs,
|
GROUP_CONCAT(DISTINCT CASE WHEN ts.role = 'lecteur' THEN s.name END) as jury_lecteurs,
|
||||||
GROUP_CONCAT(DISTINCT l.name) as languages,
|
GROUP_CONCAT(DISTINCT l.name) as languages,
|
||||||
GROUP_CONCAT(DISTINCT fmt.name) as formats,
|
GROUP_CONCAT(DISTINCT fmt.name) as formats,
|
||||||
GROUP_CONCAT(DISTINCT k.keyword) as keywords
|
GROUP_CONCAT(DISTINCT tg.name) as keywords
|
||||||
FROM theses t
|
FROM theses t
|
||||||
LEFT JOIN orientations o ON t.orientation_id = o.id
|
LEFT JOIN orientations o ON t.orientation_id = o.id
|
||||||
LEFT JOIN ap_programs ap ON t.ap_program_id = ap.id
|
LEFT JOIN ap_programs ap ON t.ap_program_id = ap.id
|
||||||
@@ -53,8 +53,8 @@ LEFT JOIN thesis_languages tl ON t.id = tl.thesis_id
|
|||||||
LEFT JOIN languages l ON tl.language_id = l.id
|
LEFT JOIN languages l ON tl.language_id = l.id
|
||||||
LEFT JOIN thesis_formats tf ON t.id = tf.thesis_id
|
LEFT JOIN thesis_formats tf ON t.id = tf.thesis_id
|
||||||
LEFT JOIN format_types fmt ON tf.format_id = fmt.id
|
LEFT JOIN format_types fmt ON tf.format_id = fmt.id
|
||||||
LEFT JOIN thesis_keywords tk ON t.id = tk.thesis_id
|
LEFT JOIN thesis_tags tt ON t.id = tt.thesis_id
|
||||||
LEFT JOIN keywords k ON tk.keyword_id = k.id
|
LEFT JOIN tags tg ON tt.tag_id = tg.id
|
||||||
GROUP BY t.id;
|
GROUP BY t.id;
|
||||||
|
|
||||||
-- Recreate public view
|
-- Recreate public view
|
||||||
|
|||||||
8
storage/migrations/006_add_composite_index.sql
Normal file
8
storage/migrations/006_add_composite_index.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-- Migration 006: Add composite covering index (is_published, year DESC) on theses
|
||||||
|
--
|
||||||
|
-- Every public-facing query filters on is_published = 1 AND orders/filters by year.
|
||||||
|
-- The existing separate idx_theses_published and idx_theses_year force the query
|
||||||
|
-- planner to pick one index and sort the other via a temp B-tree.
|
||||||
|
-- This single covering index eliminates the extra sort pass.
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_theses_pub_year ON theses(is_published, year DESC);
|
||||||
Binary file not shown.
@@ -306,6 +306,7 @@ INSERT OR IGNORE INTO pages (slug, title, content) VALUES
|
|||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_theses_year ON theses(year);
|
CREATE INDEX IF NOT EXISTS idx_theses_year ON theses(year);
|
||||||
CREATE INDEX IF NOT EXISTS idx_theses_published ON theses(is_published);
|
CREATE INDEX IF NOT EXISTS idx_theses_published ON theses(is_published);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_theses_pub_year ON theses(is_published, year DESC);
|
||||||
CREATE INDEX IF NOT EXISTS idx_theses_identifier ON theses(identifier);
|
CREATE INDEX IF NOT EXISTS idx_theses_identifier ON theses(identifier);
|
||||||
CREATE INDEX IF NOT EXISTS idx_theses_orientation ON theses(orientation_id);
|
CREATE INDEX IF NOT EXISTS idx_theses_orientation ON theses(orientation_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_theses_ap_program ON theses(ap_program_id);
|
CREATE INDEX IF NOT EXISTS idx_theses_ap_program ON theses(ap_program_id);
|
||||||
|
|||||||
BIN
storage/test.db
BIN
storage/test.db
Binary file not shown.
Reference in New Issue
Block a user