mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
perf: replace fat-view student index query with lean getPublishedAuthors()
The répertoire page was loading the full v_theses_public view (15 JOINs + 8 GROUP_CONCAT temp B-trees) via getAllPublishedTheses() just to build the student name → thesis-id map on the index page. Only two columns (id, authors) were ever consumed by the template. Add Database::getPublishedAuthors(): array - Queries thesis_authors JOIN authors directly on the theses base table - Filters on theses.is_published = 1 using the existing index - Returns only id + GROUP_CONCAT(authors) — no view expansion - Results verified identical to the old getAllPublishedTheses() output Update search.php to call getPublishedAuthors() instead. Mark getAllPublishedTheses() @deprecated in Database.php. All tests pass.
This commit is contained in:
9
TODO.md
9
TODO.md
@@ -363,12 +363,11 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
||||
with a plain table query in `searchTheses` and `getPublishedTheses`** — build the minimal JOIN set
|
||||
per query and let indexes filter `theses` first. Keep the views for reporting/admin use only.
|
||||
|
||||
- [ ] **`getAllPublishedTheses()` in `search.php`** — fetches every published thesis (all columns,
|
||||
- [x] **`getAllPublishedTheses()` in `search.php`** — fetches every published thesis (all columns,
|
||||
all JOINs) just to build the student-name index on the Répertoire page. This is a full table
|
||||
scan through the fat view. Replace with a dedicated lean query:
|
||||
`SELECT id, authors FROM v_theses_public ORDER BY authors ASC` — or add
|
||||
`Database::getPublishedAuthors(): array` that queries `thesis_authors JOIN authors` directly,
|
||||
avoiding the view entirely.
|
||||
scan through the fat view. Replaced with `Database::getPublishedAuthors(): array` that queries
|
||||
`thesis_authors JOIN authors` directly (only `id` + `authors` columns), avoiding the view entirely.
|
||||
`getAllPublishedTheses()` kept but marked `@deprecated`.
|
||||
|
||||
- [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).
|
||||
|
||||
@@ -46,8 +46,8 @@ try {
|
||||
$orientations = $db->getAllOrientations();
|
||||
$apPrograms = $db->getAllAPPrograms();
|
||||
$keywords = $db->getUsedTags();
|
||||
// Fetch all published theses for the student index (no artificial cap)
|
||||
$students = $db->getAllPublishedTheses();
|
||||
// Fetch id+authors only — lean query bypassing the fat v_theses_public view
|
||||
$students = $db->getPublishedAuthors();
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$validationError = $e->getMessage();
|
||||
$results = []; $totalItems = 0; $totalPages = 0;
|
||||
|
||||
@@ -408,6 +408,10 @@ class Database {
|
||||
/**
|
||||
* Return ALL published theses (no cap) — for internal use (student index).
|
||||
* Not exposed to user-controlled input.
|
||||
*
|
||||
* @deprecated Use getPublishedAuthors() for the répertoire student index —
|
||||
* it avoids the expensive v_theses_public view and only fetches
|
||||
* the two columns actually needed (id, authors).
|
||||
*/
|
||||
public function getAllPublishedTheses(): array {
|
||||
$stmt = $this->pdo->query(
|
||||
@@ -416,6 +420,29 @@ class Database {
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lean query for the répertoire student-name index.
|
||||
*
|
||||
* Avoids the fat v_theses_public view (15 JOINs + 8 GROUP_CONCAT B-trees).
|
||||
* Queries thesis_authors → authors directly, letting the index on
|
||||
* theses(is_published) filter the base table before any JOIN.
|
||||
*
|
||||
* Returns rows of [id => int, authors => "Name1,Name2"].
|
||||
*/
|
||||
public function getPublishedAuthors(): array {
|
||||
$stmt = $this->pdo->query(
|
||||
"SELECT t.id,
|
||||
GROUP_CONCAT(a.name ORDER BY ta.author_order ASC) AS authors
|
||||
FROM theses t
|
||||
JOIN thesis_authors ta ON ta.thesis_id = t.id
|
||||
JOIN authors a ON a.id = ta.author_id
|
||||
WHERE t.is_published = 1
|
||||
GROUP BY t.id
|
||||
ORDER BY MIN(a.name) ASC"
|
||||
);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public function getAvailableYears() {
|
||||
$sql = "SELECT DISTINCT year FROM theses WHERE is_published = 1 ORDER BY year DESC";
|
||||
$stmt = $this->pdo->query($sql);
|
||||
|
||||
@@ -1 +1 @@
|
||||
[1774694544]
|
||||
[1774701325]
|
||||
BIN
storage/test.db
BIN
storage/test.db
Binary file not shown.
Reference in New Issue
Block a user