Changes between Version 1 and Version 2 of DriverDeliveriesView


Ignore:
Timestamp:
09/14/26 00:40:31 (13 days ago)
Author:
223235
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DriverDeliveriesView

    v1 v2  
    11= Преглед: v_driver_deliveries =
    22
    3 ||= Датотека ||= `views/04_driver_deliveries_view.sql` ||
    4 ||= Шема ||= `kbnteam` ||
    5 ||= Категорија ||= Нарачки и Достави ||
    6 ||= Поврзани индекси ||= `indexes/v_driver_deliveries_index.sql` ||
    7 ||= Сложеност ||= Висока — 2 CTE + 13 табели ||
     3||= Својство ||= Вредност ||
     4|| Шема || `kbnteam` ||
     5|| Категорија || Нарачки и достави ||
     6|| Поврзани индекси || [wiki:DriverDeliveriesIndex Индекси за нарачки и достави] ||
    87
    98== Опис ==
    10 Прикажува доделување на достави и поврзаниот содржај на нарачките наменет за возачите. Го следи истиот шаблон за агрегирање на ставки (CTE `order_meals` и `order_drinks`) како `v_orders_full`, но е ориентиран кон доставата наместо кон нарачката. Корисен за екранот на возачот во мобилната/веб апликација.
     9
     10Ги прикажува доставите, доставувачите, рестораните, компаниите и поврзаните нарачки.
     11
     12Го користи прегледот на нарачки за деталите за клиентот и нарачаните производи. Се прикажуваат и доставите без назначен доставувач или поврзани нарачки.
     13
     14Еден ред за секоја клиентска нарачка во доставата. Достава без клиентски нарачки останува прикажана со NULL податоци за нарачката.
     15
     16Податоците за нарачките се добиваат преку [wiki:OrdersFullView v_orders_full]. Овој преглед е зависност на прегледот за достави.
    1117
    1218== Зависности ==
    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 Дефиниција ==
     19
     20||= Табела / преглед ||= Употреба ||
     21|| `kbnteam.delivery` || Достави, датуми, забелешки и назначени доставувачи. ||
     22|| `kbnteam.delivery_status` || Називи на статусите на доставите. ||
     23|| `kbnteam.driver` || Доставувачи и нивните ресторани. ||
     24|| `kbnteam.api_user` || Лични и контактни податоци за корисниците. ||
     25|| `kbnteam.restaurant` || Податоци за рестораните. ||
     26|| `kbnteam.company_order` || Поврзување на компаниските нарачки со компанијата и доставата. ||
     27|| `kbnteam.company` || Податоци за компаниите. ||
     28|| [wiki:OrdersFullView v_orders_full] || Преглед со детали за клиентските нарачки и листи со производи. ||
     29
     30== Излезни колони ==
     31
     32||= Колона ||= Извор / пресметка ||= Опис ||
     33|| `delivery_id` || `delivery.delivery_id` || Идентификатор на доставата. ||
     34|| `delivery_date` || `delivery.delivery_date` || Датум на доставата. ||
     35|| `delivery_notes` || `delivery.delivery_notes` || Забелешки за доставата. ||
     36|| `d_status_name` || `delivery_status.d_status_name` || Статус на доставата. ||
     37|| `driver_user_id` || `driver.user_id` || Идентификатор на доставувачот. ||
     38|| `driver_first_name` || `api_user.user_first_name` || Име на доставувачот. ||
     39|| `driver_last_name` || `api_user.user_last_name` || Презиме на доставувачот. ||
     40|| `driver_phone` || `api_user.user_phone_no` || Телефон на доставувачот. ||
     41|| `rest_id` || `restaurant.rest_id` || Идентификатор на ресторанот. ||
     42|| `rest_name` || `restaurant.rest_name` || Назив на ресторанот. ||
     43|| `comp_order_id` || `company_order.comp_order_id` || Идентификатор на компаниската нарачка. ||
     44|| `company_id` || `company.company_id` || Идентификатор на компанијата. ||
     45|| `company_name` || `company.company_name` || Назив на компанијата. ||
     46|| `order_id` || `v_orders_full.order_id` || Идентификатор на клиентската нарачка. ||
     47|| `order_datetime` || `v_orders_full.order_datetime` || Датум и време на нарачката. ||
     48|| `order_total` || `v_orders_full.order_total` || Вкупен износ на нарачката. ||
     49|| `customer_user_id` || `v_orders_full.customer_user_id` || Идентификатор на клиентот. ||
     50|| `customer_first_name` || `v_orders_full.customer_first_name` || Име на клиентот. ||
     51|| `customer_last_name` || `v_orders_full.customer_last_name` || Презиме на клиентот. ||
     52|| `customer_email` || `v_orders_full.customer_email` || Е-пошта на клиентот. ||
     53|| `meals` || `COALESCE(v_orders_full.meals, '')` || Подредена листа со називи на нарачаните јадења. ||
     54|| `drinks` || `COALESCE(v_orders_full.drinks, '')` || Подредена листа со називи на нарачаните пијалоци. ||
     55
     56== SQL дефиниција ==
     57
    2958{{{
    3059#!sql
    3160CREATE 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 )
    5861SELECT
    5962    d.delivery_id,
    … …  
    7376    o.order_datetime,
    7477    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
     78    o.customer_user_id,
     79    o.customer_first_name,
     80    o.customer_last_name,
     81    o.customer_email,
     82    COALESCE(o.meals, '') AS meals,
     83    COALESCE(o.drinks, '') AS drinks
    8184FROM kbnteam.delivery d
    8285JOIN kbnteam.delivery_status ds ON ds.d_status_id = d.d_status_id
    … …  
    8689LEFT JOIN kbnteam.company_order co ON co.delivery_id = d.delivery_id
    8790LEFT 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;
     91LEFT JOIN kbnteam.v_orders_full o ON o.comp_order_id = co.comp_order_id;
    9392}}}
    9493
    9594== Тестирање на перформанси ==
    9695
    97 === Препорачано тест прашање ===
    98 {{{
    99 #!sql
    100 SET search_path TO kbnteam;
    101 SET statement_timeout = '60s';
    102 
    103 -- Тест 1: по возач и датум на достава
     96Примерите користат илустративни идентификатори и датуми. За споредливи мерења се избираат вредности што постојат во базата и се задржуваат истите податоци, филтри, услови за кеширање и број на повторувања. Статистиките за табелите треба да бидат ажурирани во двете состојби.
     97
     98=== Тест прашалници ===
     99
     100{{{
     101#!sql
     102BEGIN READ ONLY;
     103SET LOCAL statement_timeout = '60s';
     104
     105-- Тест 1: по доставувач и датум
    104106EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
    105107SELECT * FROM kbnteam.v_driver_deliveries
    106108WHERE driver_user_id = 1
    107   AND delivery_date >= CURRENT_DATE - INTERVAL '30 days';
     109  AND delivery_date >= DATE '2026-09-01'
     110  AND delivery_date < DATE '2026-10-01';
    108111
    109112-- Тест 2: по компаниска нарачка
    … …  
    111114SELECT * FROM kbnteam.v_driver_deliveries
    112115WHERE comp_order_id = 1;
     116
     117ROLLBACK;
    113118}}}
    114119
    115120=== Резултати пред индексирање ===
    116 ||= Метрика ||= Тест 1 (возач + датум) ||= Тест 2 (comp_order) ||
     121
     122Основната состојба ги задржува индексите на примарните клучеви и уникатните ограничувања. Останатите присутни индекси се евидентираат одделно. При споредба на заеднички индекси се користи истата почетна состојба за секој преглед.
     123
     124||= Метрика ||= Тест 1 (по доставувач и датум) ||= Тест 2 (по компаниска нарачка) ||
    117125|| Planning Time || ___ ms || ___ ms ||
    118126|| Execution Time || ___ ms || ___ ms ||
    119127|| 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
     128|| Начин на читање по табела || ___ || ___ ||
     129|| Shared Hit Blocks || ___ || ___ ||
     130|| Shared Read Blocks || ___ || ___ ||
     131
     132{{{
     133-- Планови и резултати пред дополнителното индексирање:
     134
     135}}}
     136
     137=== Дополнителни и заеднички индекси ===
     138
     139`company_order(delivery_id)` има уникатен индекс. Прегледот ги користи и индексите за нарачките преку `v_orders_full`.
     140
     141||= Индекс ||= Табела и колони ||= Намена ||
     142|| `idx_company_order_company_id` || `company_order(company_id)` || Пронаоѓање компаниски нарачки по компанија. ||
     143|| `idx_customer_order_comp_order_id` || `customer_order(comp_order_id)` || Пронаоѓање клиентски нарачки по компаниска нарачка. ||
     144|| `idx_order_meal_order_id_meal_id` || `order_meal(order_id, meal_id)` || Пристап до јадењата на нарачката и групирање по order_id. ||
     145|| `idx_order_drink_order_id_drink_id` || `order_drink(order_id, drink_id)` || Пристап до пијалоците на нарачката и групирање по order_id. ||
     146|| `idx_delivery_driver_user_id_delivery_date` || `delivery(driver_user_id, delivery_date)` || Пронаоѓање достави по доставувач; во прегледите за нарачки и достави и по датум. ||
     147|| `idx_driver_rest_id` || `driver(rest_id)` || Пронаоѓање доставувачи по ресторан. ||
     148
     149{{{
     150#!sql
     151CREATE INDEX IF NOT EXISTS idx_company_order_company_id
     152ON kbnteam.company_order (company_id);
     153
     154CREATE INDEX IF NOT EXISTS idx_customer_order_comp_order_id
     155ON kbnteam.customer_order (comp_order_id);
     156
     157CREATE INDEX IF NOT EXISTS idx_order_meal_order_id_meal_id
     158ON kbnteam.order_meal (order_id, meal_id);
     159
     160CREATE INDEX IF NOT EXISTS idx_order_drink_order_id_drink_id
     161ON kbnteam.order_drink (order_id, drink_id);
     162
    131163CREATE INDEX IF NOT EXISTS idx_delivery_driver_user_id_delivery_date
    132164ON kbnteam.delivery (driver_user_id, delivery_date);
    133165
    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);
     166CREATE INDEX IF NOT EXISTS idx_driver_rest_id
     167ON kbnteam.driver (rest_id);
     168}}}
     169
     170=== Проверка на индексите ===
     171
     172{{{
     173#!sql
     174SELECT tablename, indexname, indexdef
     175FROM pg_indexes
     176WHERE schemaname = 'kbnteam'
     177  AND indexname IN (
     178    'idx_company_order_company_id',
     179    'idx_customer_order_comp_order_id',
     180    'idx_order_meal_order_id_meal_id',
     181    'idx_order_drink_order_id_drink_id',
     182    'idx_delivery_driver_user_id_delivery_date',
     183    'idx_driver_rest_id'
     184)
     185ORDER BY tablename, indexname;
    142186}}}
    143187
    144188=== Резултати по индексирање ===
    145 ||= Метрика ||= Тест 1 (возач + датум) ||= Тест 2 (comp_order) ||
     189
     190Мерењето ги користи истите тест прашалници и услови како почетното мерење.
     191
     192||= Метрика ||= Тест 1 (по доставувач и датум) ||= Тест 2 (по компаниска нарачка) ||
    146193|| Planning Time || ___ ms || ___ ms ||
    147194|| Execution Time || ___ ms || ___ ms ||
    148195|| Rows Returned || ___ || ___ ||
    149 || delivery scan || ___ || ___ ||
    150 || order_meal scan || ___ || ___ ||
    151 
    152 {{{
    153 -- Излезот од EXPLAIN ANALYZE овде (по индексирање)
     196|| Начин на читање по табела || ___ || ___ ||
     197|| Shared Hit Blocks || ___ || ___ ||
     198|| Shared Read Blocks || ___ || ___ ||
     199
     200{{{
     201-- Планови и резултати по дополнителното индексирање:
     202
    154203}}}
    155204
    156205=== Анализа на подобрување ===
    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 ||= Метрика ||= Пред ||= По ||= Δ Подобрување ||
     206
     207||= Метрика ||= Пред ||= По ||= Промена (%) ||
    164208|| Execution Time (Тест 1) || ___ ms || ___ ms || ___ % ||
    165209|| Execution Time (Тест 2) || ___ ms || ___ ms || ___ % ||
     210
     211Промената се пресметува како 100 × (време пред − време по) / време пред, кога почетното време е поголемо од нула. Негативна вредност означува побавно извршување.
     212
     213Изборот меѓу секвенцијално читање, индексно читање и други планови зависи од обемот на податоците, селективноста на филтрите и статистиките. Индексите не гарантираат забрзување или отстранување на сортирањата и спојувањата. Плановите и времињата се утврдуваат со мерење.