- perf/analysis: разбор trace (timeline_breakdown), CPU-профилей с source maps (cpuprofile_top), heap snapshots (heapdiff), циклов памяти, сравнения масштабов, ручной EXPLAIN вложенных запросов (explain_manual), API против X-DB-Time-Ms (api_split), сводка горячих точек; тесты ядра в perf/tests/test_analysis.py - perf/e2e/scenarios/hotspots.spec.ts: CPU-профиль, рендеры React, мутации DOM после фильтра, рост CSS-правил по циклам (вне run-all) - prod-сборка с source maps: PERF_SOURCEMAP=1, perf/stand.sh web-sourcemap (:8082) - perf/report-data/20261026-s1, 20261026-s2 (summary, sql, analysis, explain-manual), t5-types (иллюстрация CPU 6x) - design.md: решения T10b без обсуждения Refs #202 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 KiB
EXPLAIN (ANALYZE, BUFFERS) вложенных запросов (explain_manual.py)
Postgres 16.15 (Debian 16.15-1.pgdg13+2), work_mem по умолчанию 4MB; масштаб 1; FORM_2/AHR form_id=7, FORM_4/CAP form_id=13; app.user_id=2 (perf_rf). Каждый запрос - в транзакции с ROLLBACK.
form2_ahr_tw
FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155. Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 534.7 мс, Planning Time 24.1 мс; строк 2091; стоимость плана 119666.99
- JIT: 467 функций, 229.6 мс (emission 201.1)
- Shared Hit 52471, Shared Read 0; Temp Read/Written (узел верхнего уровня) 4/26, сумма по узлам 44/286 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| CTE Scan | page | 207.3 | 1545 | 1 | 0/0 | |
| Seq Scan | expense_item | 204.4 | 554 | 1 | 0/0 | |
| CTE Scan | aq_q | 46.4 | 438 | 546 | 4/26 | |
| Nested Loop | 35.6 | 1847 | 1 | 0/0 | ||
| CTE Scan | aq_q | 28.4 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 27.8 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 27.3 | 438 | 546 | 0/0 | |
| Nested Loop | 11.4 | 1847 | 1 | 0/0 | ||
| Hash Join | 11.3 | 1545 | 1 | 0/0 | ||
| Nested Loop | 10.9 | 1847 | 1 | 4/26 |
form2_ahr_tw.jit_off
FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155. Настройки: jit=off.
- Execution Time: 240.2 мс, Planning Time 8.1 мс; строк 2091; стоимость плана 119666.99
- JIT: нет
- Shared Hit 52443, Shared Read 0; Temp Read/Written (узел верхнего уровня) 4/26, сумма по узлам 44/286 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| CTE Scan | aq_q | 34.9 | 438 | 546 | 4/26 | |
| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | |
| Nested Loop | 20.1 | 1847 | 1 | 0/0 | ||
| Hash Join | 12.7 | 1545 | 1 | 0/0 | ||
| Nested Loop | 10.0 | 1847 | 1 | 0/0 | ||
| Nested Loop | 9.9 | 1847 | 1 | 4/26 | ||
| Nested Loop | 9.9 | 1847 | 1 | 0/0 | ||
| Nested Loop | 9.8 | 1847 | 1 | 0/0 |
form2_ahr_tw.work_mem_64MB
FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155. Настройки: work_mem=64MB.
- Execution Time: 243.2 мс, Planning Time 6.8 мс; строк 2091; стоимость плана 71314.68
- JIT: нет
- Shared Hit 14841, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| CTE Scan | aq_q | 34.9 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | |
| Nested Loop | 20.0 | 1847 | 1 | 0/0 | ||
| Hash Join | 13.0 | 1545 | 1 | 0/0 | ||
| Nested Loop | 11.3 | 1847 | 1 | 0/0 | ||
| Nested Loop | 10.3 | 1847 | 1 | 0/0 | ||
| Nested Loop | 10.2 | 1847 | 1 | 0/0 | ||
| Nested Loop | 9.9 | 1847 | 1 | 0/0 |
form2_ahr_tw.rerun_default
FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155. Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 480.8 мс, Planning Time 7.0 мс; строк 2091; стоимость плана 119666.99
- JIT: 467 функций, 211.6 мс (emission 190.5)
- Shared Hit 52443, Shared Read 0; Temp Read/Written (узел верхнего уровня) 4/26, сумма по узлам 44/286 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| CTE Scan | page | 193.7 | 1545 | 1 | 0/0 | |
| Seq Scan | expense_item | 192.9 | 554 | 1 | 0/0 | |
| CTE Scan | aq_q | 43.7 | 438 | 546 | 4/26 | |
| Nested Loop | 34.8 | 1847 | 1 | 0/0 | ||
| CTE Scan | aq_q | 30.0 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 27.8 | 438 | 546 | 0/0 | |
| CTE Scan | aq_q | 27.3 | 438 | 546 | 0/0 | |
| Nested Loop | 11.5 | 1847 | 1 | 0/0 | ||
| Hash Join | 11.0 | 1545 | 1 | 0/0 | ||
| Nested Loop | 10.9 | 1847 | 1 | 0/0 |
form2_ahr_jsonb
FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:18-38. Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 530.0 мс, Planning Time 0.6 мс; строк 2091; стоимость плана 160.08
- JIT: нет
- Shared Hit 52560, Shared Read 0; Temp Read/Written (узел верхнего уровня) 1066/1090, сумма по узлам 3202/3296 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form2_sheet_sections | 505.7 | 2091 | 1 | 4/26 | |
| WindowAgg | 17.5 | 2091 | 1 | 1066/1090 | ||
| Sort | 5.7 | 2091 | 1 | 1066/1090 | external merge 8496 | |
| Subquery Scan | 0.3 | 2091 | 1 | 1066/1090 |
form2_ahr_jsonb.jit_off
FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:18-38. Настройки: jit=off.
- Execution Time: 285.7 мс, Planning Time 0.5 мс; строк 2091; стоимость плана 160.08
- JIT: нет
- Shared Hit 52554, Shared Read 0; Temp Read/Written (узел верхнего уровня) 1066/1090, сумма по узлам 3202/3296 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form2_sheet_sections | 262.5 | 2091 | 1 | 4/26 | |
| WindowAgg | 17.3 | 2091 | 1 | 1066/1090 | ||
| Sort | 5.2 | 2091 | 1 | 1066/1090 | external merge 8496 | |
| Subquery Scan | 0.2 | 2091 | 1 | 1066/1090 |
form2_ahr_jsonb.work_mem_64MB
FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:18-38. Настройки: work_mem=64MB.
- Execution Time: 294.2 мс, Planning Time 0.5 мс; строк 2091; стоимость плана 160.08
- JIT: нет
- Shared Hit 14952, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form2_sheet_sections | 274.9 | 2091 | 1 | 0/0 | |
| WindowAgg | 17.7 | 2091 | 1 | 0/0 | ||
| Sort | 1.2 | 2091 | 1 | 0/0 | quicksort 8595 | |
| Subquery Scan | 0.3 | 2091 | 1 | 0/0 |
form2_ahr_jsonb.rerun_default
FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: api/alembic/versions/sql/0033_form2_old_sort.sql:18-38. Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 553.3 мс, Planning Time 0.5 мс; строк 2091; стоимость плана 160.08
- JIT: нет
- Shared Hit 52554, Shared Read 0; Temp Read/Written (узел верхнего уровня) 1066/1090, сумма по узлам 3202/3296 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form2_sheet_sections | 530.7 | 2091 | 1 | 4/26 | |
| WindowAgg | 17.2 | 2091 | 1 | 1066/1090 | ||
| Sort | 4.8 | 2091 | 1 | 1066/1090 | external merge 8496 | |
| Subquery Scan | 0.2 | 2091 | 1 | 1066/1090 |
form_view_ahr
FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view). Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 547.0 мс, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25
- JIT: нет
- Shared Hit 53000, Shared Read 0; Temp Read/Written (узел верхнего уровня) 3246/3270, сумма по узлам 3246/3270 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form_view | 546.5 | 2092 | 1 | 3246/3270 |
form_view_ahr.jit_off
FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view). Настройки: jit=off.
- Execution Time: 721.7 мс, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25
- JIT: нет
- Shared Hit 47794, Shared Read 0; Temp Read/Written (узел верхнего уровня) 3246/3270, сумма по узлам 3246/3270 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form_view | 721.4 | 2092 | 1 | 3246/3270 |
form_view_ahr.work_mem_64MB
FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view). Настройки: work_mem=64MB.
- Execution Time: 634.6 мс, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25
- JIT: нет
- Shared Hit 47680, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form_view | 634.4 | 2092 | 1 | 0/0 |
form_view_ahr.rerun_default
FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view). Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 624.1 мс, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25
- JIT: нет
- Shared Hit 47680, Shared Read 0; Temp Read/Written (узел верхнего уровня) 3246/3270, сумма по узлам 3246/3270 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form_view | 623.8 | 2092 | 1 | 3246/3270 |
form4_cap_sheet
FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow). Источник: api/alembic/versions/sql/0012_del_project.sql:1097-…. Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 1597.8 мс, Planning Time 1.7 мс; строк 299; стоимость плана 5166.81
- JIT: нет
- Shared Hit 44536, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Aggregate | 513.3 | 6 | 1 | 0/0 | ||
| Aggregate | 510.2 | 2 | 1 | 0/0 | ||
| Aggregate | 498.4 | 1 | 1 | 0/0 | ||
| CTE Scan | inp | 70.9 | 290 | 1 | 0/0 | |
| Function Scan | v_form4_sheet_sections | 42.3 | 290 | 1 | 0/0 | |
| CTE Scan | up | 26.7 | 1 | 290 | 0/0 | |
| Hash Join | 12.8 | 1 | 609 | 0/0 | ||
| Seq Scan | expense_item | 12.8 | 581 | 609 | 0/0 | |
| CTE Scan | inp | 0.6 | 290 | 1 | 0/0 | |
| Recursive Union | 0.5 | 3 | 290 | 0/0 |
form4_cap_sheet.jit_off
FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow). Источник: api/alembic/versions/sql/0012_del_project.sql:1097-…. Настройки: jit=off.
- Execution Time: 1651.0 мс, Planning Time 1.2 мс; строк 299; стоимость плана 5166.81
- JIT: нет
- Shared Hit 44463, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Aggregate | 546.6 | 1 | 1 | 0/0 | ||
| Aggregate | 532.0 | 6 | 1 | 0/0 | ||
| Aggregate | 505.9 | 2 | 1 | 0/0 | ||
| CTE Scan | inp | 60.9 | 290 | 1 | 0/0 | |
| Function Scan | v_form4_sheet_sections | 36.0 | 290 | 1 | 0/0 | |
| CTE Scan | up | 23.5 | 1 | 290 | 0/0 | |
| Hash Join | 12.2 | 1 | 609 | 0/0 | ||
| Seq Scan | expense_item | 11.0 | 581 | 609 | 0/0 | |
| CTE Scan | inp | 0.6 | 290 | 1 | 0/0 | |
| Index Scan | budget_line | 0.3 | 1 | 290 | 0/0 |
form_view_form4_cap
FORM_4/CAP: вызов v3.v_form_view (как GET листа). Источник: api/src/repository (sheet_repository). Настройки: по умолчанию (work_mem 4MB, jit on).
- Execution Time: 1557.3 мс, Planning Time 0.0 мс; строк 300; стоимость плана 10.25
- JIT: нет
- Shared Hit 44516, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form_view | 1557.3 | 300 | 1 | 0/0 |
form_view_form4_cap.jit_off
FORM_4/CAP: вызов v3.v_form_view (как GET листа). Источник: api/src/repository (sheet_repository). Настройки: jit=off.
- Execution Time: 1565.3 мс, Planning Time 0.0 мс; строк 300; стоимость плана 10.25
- JIT: нет
- Shared Hit 44497, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ
| узел | объект | excl мс | строк | loops | temp r/w | sort |
|---|---|---|---|---|---|---|
| Function Scan | v_form_view | 1565.2 | 300 | 1 | 0/0 |
Хронометраж вызовов v3.v_form_view (как GET листа), мс
По 10 вызовов на вариант после 1 прогрева, клиент asyncpg; медиана / мин / макс.
| вызов | настройки | медиана | мин | макс |
|---|---|---|---|---|
| FORM_2/AHR form 7 | по умолчанию | 624.6 | 617.5 | 642.2 |
| FORM_2/AHR form 7 | jit=off | 618.7 | 614.3 | 656.9 |
| FORM_2/AHR form 7 | work_mem=64MB | 618.9 | 611.7 | 643.2 |
| FORM_2/AHR form 7 | jit=off, work_mem=64MB | 615.3 | 603.9 | 635.1 |
| FORM_4/CAP form 13 | по умолчанию | 1551.1 | 1531.9 | 1595.0 |
| FORM_4/CAP form 13 | jit=off | 1542.1 | 1530.2 | 1557.5 |
| FORM_4/CAP form 13 | work_mem=64MB | 1549.0 | 1531.2 | 1594.7 |
| FORM_4/CAP form 13 | jit=off, work_mem=64MB | 1545.9 | 1534.9 | 1559.2 |
Внутри v3.v_form_view(FORM_2/AHR): pg_stat_statements за 8 вызовов в новом соединении
Время вызовов по порядку, мс: [579.8, 531.9, 557.7, 534.2, 527.8, 647.7, 690.3, 638.2]
| запрос | calls | mean мс | total мс | jit функций | jit мс | temp written | toplevel |
|---|---|---|---|---|---|---|---|
SELECT count(*) FROM v3.v_form_view($1, $2, $3::text[], $4::varchar) |
8 | 587.7 | 4701.5 | 0 | 0.0 | 26160 | True |
SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections) |
8 | 586.1 | 4688.7 | 0 | 0.0 | 26152 | False |
SELECT j.row_type, j.depth, ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order, jsonb |
8 | 582.4 | 4659.0 | 0 | 0.0 | 17432 | False |
WITH tw AS ( SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, t.depth, t.pa |
8 | 471.4 | 3771.3 | 2335 | 1106.4 | 208 | False |