| Version 3 (modified by , 13 days ago) ( diff ) |
|---|
Преглед: v_menu_meal
| Својство | Вредност |
|---|---|
| Шема | kbnteam
|
| Категорија | Мени и каталог |
| Поврзани индекси | Индекси за мени и каталог |
Опис
Ги прикажува јадењата со категорија, ресторан, состојки и алергени.
Состојките и алергените се прикажуваат како азбучно подредени листи без повторувања. Се прикажуваат и јадењата без наведени состојки или алергени.
Еден ред за секое јадење. Состојките и алергените се азбучно подредени, без повторување на називите.
Зависности
| Табела / преглед | Употреба |
|---|---|
kbnteam.meal_ingredient | Врски меѓу јадењата и состојките. |
kbnteam.ingredient | Називи на состојките. |
kbnteam.alergen_ingredient | Врски меѓу состојките и алергените. |
kbnteam.alergen | Називи на алергените. |
kbnteam.meal | Јадења, цени и поврзаност со категорија и ресторан. |
kbnteam.category | Категории на јадења. |
kbnteam.restaurant | Податоци за рестораните. |
Излезни колони
| Колона | Извор / пресметка | Опис |
|---|---|---|
meal_id | meal.meal_id | Идентификатор на јадењето. |
meal_name | meal.meal_name | Назив на јадењето. |
meal_description | meal.meal_description | Опис на јадењето. |
meal_price | meal.meal_price | Цена на јадењето. |
meal_weight | meal.meal_weight | Тежина на јадењето. |
cat_id | category.cat_id | Идентификатор на категоријата. |
cat_name | category.cat_name | Назив на категоријата. |
rest_id | restaurant.rest_id | Идентификатор на ресторанот. |
rest_name | restaurant.rest_name | Назив на ресторанот. |
ingredients | COALESCE(meal_ingredients.ingredients, '') | Подредена листа со називи на состојки. |
allergens | COALESCE(meal_allergens.allergens, '') | Подредена листа со називи на алергени. |
SQL дефиниција
CREATE OR REPLACE VIEW kbnteam.v_menu_meal AS
WITH meal_ingredients AS (
SELECT
mi.meal_id,
string_agg(DISTINCT i.ingr_name, ', ' ORDER BY i.ingr_name) AS ingredients
FROM kbnteam.meal_ingredient mi
JOIN kbnteam.ingredient i ON i.ingr_id = mi.ingr_id
GROUP BY mi.meal_id
),
meal_allergens AS (
SELECT
mi.meal_id,
string_agg(DISTINCT a.alergen_name, ', ' ORDER BY a.alergen_name) AS allergens
FROM kbnteam.meal_ingredient mi
JOIN kbnteam.alergen_ingredient ai ON ai.ingr_id = mi.ingr_id
JOIN kbnteam.alergen a ON a.alergen_id = ai.alergen_id
GROUP BY mi.meal_id
)
SELECT
m.meal_id,
m.meal_name,
m.meal_description,
m.meal_price,
m.meal_weight,
c.cat_id,
c.cat_name,
r.rest_id,
r.rest_name,
COALESCE(mi.ingredients, '') AS ingredients,
COALESCE(ma.allergens, '') AS allergens
FROM kbnteam.meal m
JOIN kbnteam.category c ON c.cat_id = m.cat_id
JOIN kbnteam.restaurant r ON r.rest_id = m.rest_id
LEFT JOIN meal_ingredients mi ON mi.meal_id = m.meal_id
LEFT JOIN meal_allergens ma ON ma.meal_id = m.meal_id;
Тестирање на перформанси
Мерењата се евидентирани во DBeaver на 14 септември 2026 година. „Пред индексирање“ и „по индексирање“ ги означуваат групите наведени како „без индекси“ и „со индекси“ во евиденцијата. Точниот сет присутни индекси во секоја група не е евидентиран; „без индекси“ не потврдува отсуство на индекси од примарни и уникатни клучеви.
Наведените времиња се клиентски мерења од DBeaver, а не серверските Planning Time и Execution Time од EXPLAIN ANALYZE. Нема приложени планови, типови на скенирање или податоци за баферите. Вредностите се во милисекунди (ms).
Измерен прашалник
SELECT * FROM kbnteam.v_menu_meal WHERE rest_id = 36 AND cat_id = 5;
Резултати пред индексирање
| Метрика | Измерен резултат |
|---|---|
| Клиентско време (ms) | 106 |
| Приказ на мерењето | Статистика за 2 наредби: 106 ms извршување, 0 ms преземање, 106 ms вкупно |
| Прикажани / преземени редови | Не е утврден од приказот на статистиката |
| Planning Time / Execution Time од EXPLAIN | Не се измерени |
| План, тип на скенирање и бафери | Не се приложени |
Дополнителни и заеднички индекси
Уникатното ограничување uq_meal_restaurant_name веќе го покрива пребарувањето по ресторан. Обратниот редослед на колоните во индексите за состојки и алергени овозможува пристап од јадење кон состојка и од состојка кон алерген.
| Индекс | Табела и колони | Намена |
|---|---|---|
idx_meal_cat_id_meal_id | meal(cat_id, meal_id) | Пребарување јадења по категорија. |
idx_meal_ingredient_meal_id_ingr_id | meal_ingredient(meal_id, ingr_id) | Пристап до состојките на јадењето и групирање по meal_id. |
idx_alergen_ingredient_ingr_id_alergen_id | alergen_ingredient(ingr_id, alergen_id) | Пристап до алергените поврзани со состојката. |
CREATE INDEX IF NOT EXISTS idx_meal_cat_id_meal_id ON kbnteam.meal (cat_id, meal_id); CREATE INDEX IF NOT EXISTS idx_meal_ingredient_meal_id_ingr_id ON kbnteam.meal_ingredient (meal_id, ingr_id); CREATE INDEX IF NOT EXISTS idx_alergen_ingredient_ingr_id_alergen_id ON kbnteam.alergen_ingredient (ingr_id, alergen_id);
Проверка на индексите
SELECT tablename, indexname, indexdef
FROM pg_indexes
WHERE schemaname = 'kbnteam'
AND indexname IN (
'idx_meal_cat_id_meal_id',
'idx_meal_ingredient_meal_id_ingr_id',
'idx_alergen_ingredient_ingr_id_alergen_id'
)
ORDER BY tablename, indexname;
Резултати по индексирање
| Метрика | Измерен резултат |
|---|---|
| Клиентско време (ms) | 44 |
| Приказ на мерењето | Време прикажано со резултатот во DBeaver |
| Прикажани / преземени редови | 0 |
| Planning Time / Execution Time од EXPLAIN | Не се измерени |
| План, тип на скенирање и бафери | Не се приложени |
Анализа на резултатите
| Метрика | Пред | По | Промена на времето |
|---|---|---|---|
| Клиентско време (ms) | 106 | 44 | -58,5% |
Аритметичката разлика е 62 ms (58,5%) пократко време. Сепак, 106 ms е вкупно време во статистика за 2 наредби, а 44 ms е време од приказот на празен резултат. Ова не е контролирана споредба на изолирани SELECT извршувања. Потребни се повторени мерења со ист начин на мерење и пример што враќа јадења.
Промената се пресметува како 100 × (време по - време пред) / време пред. Негативна вредност значи пократко време, а позитивна подолго време. Процентот ја опишува разликата меѓу прикажаните вредности.
Ова се поединечни набљудувања. Не се евидентирани контролирани повторувања, исти услови за кеширање и оптоварување или точните дефиниции на присутните индекси. Затоа промената на времето не е доказ дека индексите се единствената причина. Не се приложени мерења за INSERT, UPDATE и DELETE.
Дополнително тестирање - сè уште неизмерено
Следниот прашалник служи за ново мерење на серверскиот план со истиот филтер. Неговите резултати не се пополнети со клиентските времиња наведени погоре. За споредба се задржуваат исти податоци и поставки, се евидентираат присутните индекси, се ажурираат статистиките и се прават повеќе повторувања во двете состојби. Се споредуваат медијаната на времињата и плановите.
BEGIN READ ONLY; SET LOCAL statement_timeout = '60s'; EXPLAIN (ANALYZE, BUFFERS, VERBOSE) SELECT * FROM kbnteam.v_menu_meal WHERE rest_id = 36 AND cat_id = 5; ROLLBACK;
| Метрика за дополнителното тестирање | Пред | По |
|---|---|---|
| Planning Time (ms) | Не е измерено | Не е измерено |
| Execution Time (ms) | Не е измерено | Не е измерено |
| Тип на скенирање по табела | Не е евидентиран | Не е евидентиран |
| Shared Hit Blocks / Shared Read Blocks | Не се измерени | Не се измерени |
