wiki:MenuMealView

Version 3 (modified by 223235, 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 Не се измерени Не се измерени
Note: See TracWiki for help on using the wiki.