= Преглед: v_driver_deliveries = ||= Датотека ||= `views/04_driver_deliveries_view.sql` || ||= Шема ||= `kbnteam` || ||= Категорија ||= Нарачки и Достави || ||= Поврзани индекси ||= `indexes/v_driver_deliveries_index.sql` || ||= Сложеност ||= Висока — 2 CTE + 13 табели || == Опис == Прикажува доделување на достави и поврзаниот содржај на нарачките наменет за возачите. Го следи истиот шаблон за агрегирање на ставки (CTE `order_meals` и `order_drinks`) како `v_orders_full`, но е ориентиран кон доставата наместо кон нарачката. Корисен за екранот на возачот во мобилната/веб апликација. == Зависности == ||= Табела ||= Тип на употреба || || `kbnteam.delivery` || Главна табела || || `kbnteam.delivery_status` || JOIN — статус на достава || || `kbnteam.driver` || LEFT JOIN — возач || || `kbnteam.api_user` || LEFT JOIN (×2) — детали за возач и купувач || || `kbnteam.restaurant` || LEFT JOIN — ресторан на возачот || || `kbnteam.company_order` || LEFT JOIN — компаниска нарачка || || `kbnteam.company` || LEFT JOIN — компанија || || `kbnteam.customer_order` || LEFT JOIN — нарачка || || `kbnteam.customer` || LEFT JOIN — купувач || || `kbnteam.order_meal` || LEFT JOIN (CTE) — оброци || || `kbnteam.meal` || JOIN (CTE) — назив на оброк || || `kbnteam.order_drink` || LEFT JOIN (CTE) — пијачи || || `kbnteam.drink` || JOIN (CTE) — назив на пијач || == SQL Дефиниција == {{{ #!sql CREATE OR REPLACE VIEW kbnteam.v_driver_deliveries AS WITH order_meals AS ( SELECT x.order_id, string_agg(x.meal_name, ', ' ORDER BY x.meal_name) AS meals FROM ( SELECT DISTINCT om.order_id, m.meal_name FROM kbnteam.order_meal om JOIN kbnteam.meal m ON m.meal_id = om.meal_id ) x GROUP BY x.order_id ), order_drinks AS ( SELECT x.order_id, string_agg(x.drink_name, ', ' ORDER BY x.drink_name) AS drinks FROM ( SELECT DISTINCT od.order_id, d.drink_name FROM kbnteam.order_drink od JOIN kbnteam.drink d ON d.drink_id = od.drink_id ) x GROUP BY x.order_id ) SELECT d.delivery_id, d.delivery_date, d.delivery_notes, ds.d_status_name, drv.user_id AS driver_user_id, du.user_first_name AS driver_first_name, du.user_last_name AS driver_last_name, du.user_phone_no AS driver_phone, r.rest_id, r.rest_name, co.comp_order_id, cmp.company_id, cmp.company_name, o.order_id, o.order_datetime, o.order_total, cu.user_id AS customer_user_id, au.user_first_name AS customer_first_name, au.user_last_name AS customer_last_name, au.user_email AS customer_email, COALESCE(om.meals, '') AS meals, COALESCE(od.drinks, '') AS drinks FROM kbnteam.delivery d JOIN kbnteam.delivery_status ds ON ds.d_status_id = d.d_status_id LEFT JOIN kbnteam.driver drv ON drv.user_id = d.driver_user_id LEFT JOIN kbnteam.api_user du ON du.user_id = drv.user_id LEFT JOIN kbnteam.restaurant r ON r.rest_id = drv.rest_id LEFT JOIN kbnteam.company_order co ON co.delivery_id = d.delivery_id LEFT JOIN kbnteam.company cmp ON cmp.company_id = co.company_id LEFT JOIN kbnteam.customer_order o ON o.comp_order_id = co.comp_order_id LEFT JOIN kbnteam.customer cu ON cu.user_id = o.customer_user_id LEFT JOIN kbnteam.api_user au ON au.user_id = cu.user_id LEFT JOIN order_meals om ON om.order_id = o.order_id LEFT JOIN order_drinks od ON od.order_id = o.order_id; }}} == Тестирање на перформанси == === Препорачано тест прашање === {{{ #!sql SET search_path TO kbnteam; SET statement_timeout = '60s'; -- Тест 1: по возач и датум на достава EXPLAIN (ANALYZE, BUFFERS, VERBOSE) SELECT * FROM kbnteam.v_driver_deliveries WHERE driver_user_id = 1 AND delivery_date >= CURRENT_DATE - INTERVAL '30 days'; -- Тест 2: по компаниска нарачка EXPLAIN (ANALYZE, BUFFERS, VERBOSE) SELECT * FROM kbnteam.v_driver_deliveries WHERE comp_order_id = 1; }}} === Резултати пред индексирање === ||= Метрика ||= Тест 1 (возач + датум) ||= Тест 2 (comp_order) || || Planning Time || ___ ms || ___ ms || || Execution Time || ___ ms || ___ ms || || Rows Returned || ___ || ___ || || delivery scan || ___ || ___ || || order_meal scan || ___ || ___ || {{{ -- Излезот од EXPLAIN ANALYZE овде (пред индексирање) }}} === Применети индекси === {{{ #!sql -- indexes/v_driver_deliveries_index.sql CREATE INDEX IF NOT EXISTS idx_delivery_driver_user_id_delivery_date ON kbnteam.delivery (driver_user_id, delivery_date); CREATE INDEX IF NOT EXISTS idx_order_meal_order_id_meal_id ON kbnteam.order_meal (order_id, meal_id); CREATE INDEX IF NOT EXISTS idx_order_drink_order_id_drink_id ON kbnteam.order_drink (order_id, drink_id); CREATE INDEX IF NOT EXISTS idx_customer_order_comp_order_id ON kbnteam.customer_order (comp_order_id); }}} === Резултати по индексирање === ||= Метрика ||= Тест 1 (возач + датум) ||= Тест 2 (comp_order) || || Planning Time || ___ ms || ___ ms || || Execution Time || ___ ms || ___ ms || || Rows Returned || ___ || ___ || || delivery scan || ___ || ___ || || order_meal scan || ___ || ___ || {{{ -- Излезот од EXPLAIN ANALYZE овде (по индексирање) }}} === Анализа на подобрување === ||= Индекс ||= Помага на ||= Очекувана промена || || `idx_delivery_driver_user_id_delivery_date` || Тест 1 — филтрирање по возач и датум || Seq Scan → Index Scan || || `idx_customer_order_comp_order_id` || Тест 2 и JOIN со `company_order` || Seq Scan → Index Scan || || `idx_order_meal_order_id_meal_id` || CTE агрегација || Seq Scan → Index Scan || || `idx_order_drink_order_id_drink_id` || CTE агрегација || Seq Scan → Index Scan || ||= Метрика ||= Пред ||= По ||= Δ Подобрување || || Execution Time (Тест 1) || ___ ms || ___ ms || ___ % || || Execution Time (Тест 2) || ___ ms || ___ ms || ___ % ||