| | 1 | = Преглед: v_driver_deliveries = |
| | 2 | |
| | 3 | ||= Датотека ||= `views/04_driver_deliveries_view.sql` || |
| | 4 | ||= Шема ||= `kbnteam` || |
| | 5 | ||= Категорија ||= Нарачки и Достави || |
| | 6 | ||= Поврзани индекси ||= `indexes/v_driver_deliveries_index.sql` || |
| | 7 | ||= Сложеност ||= Висока — 2 CTE + 13 табели || |
| | 8 | |
| | 9 | == Опис == |
| | 10 | Прикажува доделување на достави и поврзаниот содржај на нарачките наменет за возачите. Го следи истиот шаблон за агрегирање на ставки (CTE `order_meals` и `order_drinks`) како `v_orders_full`, но е ориентиран кон доставата наместо кон нарачката. Корисен за екранот на возачот во мобилната/веб апликација. |
| | 11 | |
| | 12 | == Зависности == |
| | 13 | ||= Табела ||= Тип на употреба || |
| | 14 | || `kbnteam.delivery` || Главна табела || |
| | 15 | || `kbnteam.delivery_status` || JOIN — статус на достава || |
| | 16 | || `kbnteam.driver` || LEFT JOIN — возач || |
| | 17 | || `kbnteam.api_user` || LEFT JOIN (×2) — детали за возач и купувач || |
| | 18 | || `kbnteam.restaurant` || LEFT JOIN — ресторан на возачот || |
| | 19 | || `kbnteam.company_order` || LEFT JOIN — компаниска нарачка || |
| | 20 | || `kbnteam.company` || LEFT JOIN — компанија || |
| | 21 | || `kbnteam.customer_order` || LEFT JOIN — нарачка || |
| | 22 | || `kbnteam.customer` || LEFT JOIN — купувач || |
| | 23 | || `kbnteam.order_meal` || LEFT JOIN (CTE) — оброци || |
| | 24 | || `kbnteam.meal` || JOIN (CTE) — назив на оброк || |
| | 25 | || `kbnteam.order_drink` || LEFT JOIN (CTE) — пијачи || |
| | 26 | || `kbnteam.drink` || JOIN (CTE) — назив на пијач || |
| | 27 | |
| | 28 | == SQL Дефиниција == |
| | 29 | {{{ |
| | 30 | #!sql |
| | 31 | CREATE OR REPLACE VIEW kbnteam.v_driver_deliveries AS |
| | 32 | WITH order_meals AS ( |
| | 33 | SELECT |
| | 34 | x.order_id, |
| | 35 | string_agg(x.meal_name, ', ' ORDER BY x.meal_name) AS meals |
| | 36 | FROM ( |
| | 37 | SELECT DISTINCT |
| | 38 | om.order_id, |
| | 39 | m.meal_name |
| | 40 | FROM kbnteam.order_meal om |
| | 41 | JOIN kbnteam.meal m ON m.meal_id = om.meal_id |
| | 42 | ) x |
| | 43 | GROUP BY x.order_id |
| | 44 | ), |
| | 45 | order_drinks AS ( |
| | 46 | SELECT |
| | 47 | x.order_id, |
| | 48 | string_agg(x.drink_name, ', ' ORDER BY x.drink_name) AS drinks |
| | 49 | FROM ( |
| | 50 | SELECT DISTINCT |
| | 51 | od.order_id, |
| | 52 | d.drink_name |
| | 53 | FROM kbnteam.order_drink od |
| | 54 | JOIN kbnteam.drink d ON d.drink_id = od.drink_id |
| | 55 | ) x |
| | 56 | GROUP BY x.order_id |
| | 57 | ) |
| | 58 | SELECT |
| | 59 | d.delivery_id, |
| | 60 | d.delivery_date, |
| | 61 | d.delivery_notes, |
| | 62 | ds.d_status_name, |
| | 63 | drv.user_id AS driver_user_id, |
| | 64 | du.user_first_name AS driver_first_name, |
| | 65 | du.user_last_name AS driver_last_name, |
| | 66 | du.user_phone_no AS driver_phone, |
| | 67 | r.rest_id, |
| | 68 | r.rest_name, |
| | 69 | co.comp_order_id, |
| | 70 | cmp.company_id, |
| | 71 | cmp.company_name, |
| | 72 | o.order_id, |
| | 73 | o.order_datetime, |
| | 74 | o.order_total, |
| | 75 | cu.user_id AS customer_user_id, |
| | 76 | au.user_first_name AS customer_first_name, |
| | 77 | au.user_last_name AS customer_last_name, |
| | 78 | au.user_email AS customer_email, |
| | 79 | COALESCE(om.meals, '') AS meals, |
| | 80 | COALESCE(od.drinks, '') AS drinks |
| | 81 | FROM kbnteam.delivery d |
| | 82 | JOIN kbnteam.delivery_status ds ON ds.d_status_id = d.d_status_id |
| | 83 | LEFT JOIN kbnteam.driver drv ON drv.user_id = d.driver_user_id |
| | 84 | LEFT JOIN kbnteam.api_user du ON du.user_id = drv.user_id |
| | 85 | LEFT JOIN kbnteam.restaurant r ON r.rest_id = drv.rest_id |
| | 86 | LEFT JOIN kbnteam.company_order co ON co.delivery_id = d.delivery_id |
| | 87 | LEFT JOIN kbnteam.company cmp ON cmp.company_id = co.company_id |
| | 88 | LEFT JOIN kbnteam.customer_order o ON o.comp_order_id = co.comp_order_id |
| | 89 | LEFT JOIN kbnteam.customer cu ON cu.user_id = o.customer_user_id |
| | 90 | LEFT JOIN kbnteam.api_user au ON au.user_id = cu.user_id |
| | 91 | LEFT JOIN order_meals om ON om.order_id = o.order_id |
| | 92 | LEFT JOIN order_drinks od ON od.order_id = o.order_id; |
| | 93 | }}} |
| | 94 | |
| | 95 | == Тестирање на перформанси == |
| | 96 | |
| | 97 | === Препорачано тест прашање === |
| | 98 | {{{ |
| | 99 | #!sql |
| | 100 | SET search_path TO kbnteam; |
| | 101 | SET statement_timeout = '60s'; |
| | 102 | |
| | 103 | -- Тест 1: по возач и датум на достава |
| | 104 | EXPLAIN (ANALYZE, BUFFERS, VERBOSE) |
| | 105 | SELECT * FROM kbnteam.v_driver_deliveries |
| | 106 | WHERE driver_user_id = 1 |
| | 107 | AND delivery_date >= CURRENT_DATE - INTERVAL '30 days'; |
| | 108 | |
| | 109 | -- Тест 2: по компаниска нарачка |
| | 110 | EXPLAIN (ANALYZE, BUFFERS, VERBOSE) |
| | 111 | SELECT * FROM kbnteam.v_driver_deliveries |
| | 112 | WHERE comp_order_id = 1; |
| | 113 | }}} |
| | 114 | |
| | 115 | === Резултати пред индексирање === |
| | 116 | ||= Метрика ||= Тест 1 (возач + датум) ||= Тест 2 (comp_order) || |
| | 117 | || Planning Time || ___ ms || ___ ms || |
| | 118 | || Execution Time || ___ ms || ___ ms || |
| | 119 | || Rows Returned || ___ || ___ || |
| | 120 | || delivery scan || ___ || ___ || |
| | 121 | || order_meal scan || ___ || ___ || |
| | 122 | |
| | 123 | {{{ |
| | 124 | -- Излезот од EXPLAIN ANALYZE овде (пред индексирање) |
| | 125 | }}} |
| | 126 | |
| | 127 | === Применети индекси === |
| | 128 | {{{ |
| | 129 | #!sql |
| | 130 | -- indexes/v_driver_deliveries_index.sql |
| | 131 | CREATE INDEX IF NOT EXISTS idx_delivery_driver_user_id_delivery_date |
| | 132 | ON kbnteam.delivery (driver_user_id, delivery_date); |
| | 133 | |
| | 134 | CREATE INDEX IF NOT EXISTS idx_order_meal_order_id_meal_id |
| | 135 | ON kbnteam.order_meal (order_id, meal_id); |
| | 136 | |
| | 137 | CREATE INDEX IF NOT EXISTS idx_order_drink_order_id_drink_id |
| | 138 | ON kbnteam.order_drink (order_id, drink_id); |
| | 139 | |
| | 140 | CREATE INDEX IF NOT EXISTS idx_customer_order_comp_order_id |
| | 141 | ON kbnteam.customer_order (comp_order_id); |
| | 142 | }}} |
| | 143 | |
| | 144 | === Резултати по индексирање === |
| | 145 | ||= Метрика ||= Тест 1 (возач + датум) ||= Тест 2 (comp_order) || |
| | 146 | || Planning Time || ___ ms || ___ ms || |
| | 147 | || Execution Time || ___ ms || ___ ms || |
| | 148 | || Rows Returned || ___ || ___ || |
| | 149 | || delivery scan || ___ || ___ || |
| | 150 | || order_meal scan || ___ || ___ || |
| | 151 | |
| | 152 | {{{ |
| | 153 | -- Излезот од EXPLAIN ANALYZE овде (по индексирање) |
| | 154 | }}} |
| | 155 | |
| | 156 | === Анализа на подобрување === |
| | 157 | ||= Индекс ||= Помага на ||= Очекувана промена || |
| | 158 | || `idx_delivery_driver_user_id_delivery_date` || Тест 1 — филтрирање по возач и датум || Seq Scan → Index Scan || |
| | 159 | || `idx_customer_order_comp_order_id` || Тест 2 и JOIN со `company_order` || Seq Scan → Index Scan || |
| | 160 | || `idx_order_meal_order_id_meal_id` || CTE агрегација || Seq Scan → Index Scan || |
| | 161 | || `idx_order_drink_order_id_drink_id` || CTE агрегација || Seq Scan → Index Scan || |
| | 162 | |
| | 163 | ||= Метрика ||= Пред ||= По ||= Δ Подобрување || |
| | 164 | || Execution Time (Тест 1) || ___ ms || ___ ms || ___ % || |
| | 165 | || Execution Time (Тест 2) || ___ ms || ___ ms || ___ % || |