| | 1 | = Преглед: v_company_billing_overview = |
| | 2 | |
| | 3 | ||= Датотека ||= `views/08_company_billing_view.sql` || |
| | 4 | ||= Шема ||= `kbnteam` || |
| | 5 | ||= Категорија ||= Договори, Фактурирање и Верност || |
| | 6 | ||= Поврзани индекси ||= `indexes/v_company_billing_overview_index.sql` || |
| | 7 | |
| | 8 | == Опис == |
| | 9 | Прикажува вкупни износи на фактури, бројот на нарачки на купувачи и бројот на договори по компанија. Користи два CTE: `company_contracts` го брои бројот на договори по компанија, а `invoice_totals` ги агрегира вкупните износи по фактура. Важен преглед за финансиски извештај и прикажување на фактури во администраторски панел. |
| | 10 | |
| | 11 | == Зависности == |
| | 12 | ||= Табела ||= Тип на употреба || |
| | 13 | || `kbnteam.invoice` || Главна табела || |
| | 14 | || `kbnteam.company_order` || JOIN — компаниска нарачка || |
| | 15 | || `kbnteam.customer_order` || LEFT JOIN — нарачки (за вкупен износ) || |
| | 16 | || `kbnteam.contract` || LEFT JOIN (CTE) — договори на компанијата || |
| | 17 | || `kbnteam.company` || JOIN — компанија || |
| | 18 | |
| | 19 | == Излезни колони == |
| | 20 | ||= Колона ||= Извор ||= Опис || |
| | 21 | || `invoice_id` || `invoice` || Примарен клуч на фактурата || |
| | 22 | || `comp_order_id` || `invoice` || Поврзана компаниска нарачка || |
| | 23 | || `company_id` || `company` || ID на компанијата || |
| | 24 | || `company_name` || `company` || Назив на компанијата || |
| | 25 | || `company_address` || `company` || Адреса на компанијата || |
| | 26 | || `delivery_id` || `company_order` || ID на доставата || |
| | 27 | || `customer_order_count` || CTE `invoice_totals` || Број нарачки на купувачи || |
| | 28 | || `invoice_amount` || CTE `invoice_totals` || Вкупен износ на фактурата || |
| | 29 | || `contract_count` || CTE `company_contracts` || Број на договори на компанијата || |
| | 30 | |
| | 31 | == SQL Дефиниција == |
| | 32 | {{{ |
| | 33 | #!sql |
| | 34 | CREATE OR REPLACE VIEW kbnteam.v_company_billing_overview AS |
| | 35 | WITH company_contracts AS ( |
| | 36 | SELECT |
| | 37 | ct.company_id, |
| | 38 | COUNT(*) AS contract_count |
| | 39 | FROM kbnteam.contract ct |
| | 40 | GROUP BY ct.company_id |
| | 41 | ), |
| | 42 | invoice_totals AS ( |
| | 43 | SELECT |
| | 44 | i.invoice_id, |
| | 45 | i.comp_order_id, |
| | 46 | co.company_id, |
| | 47 | co.delivery_id, |
| | 48 | COUNT(o.order_id) AS customer_order_count, |
| | 49 | COALESCE(SUM(o.order_total), 0)::numeric(14,2) AS invoice_amount |
| | 50 | FROM kbnteam.invoice i |
| | 51 | JOIN kbnteam.company_order co ON co.comp_order_id = i.comp_order_id |
| | 52 | LEFT JOIN kbnteam.customer_order o ON o.comp_order_id = co.comp_order_id |
| | 53 | GROUP BY i.invoice_id, i.comp_order_id, co.company_id, co.delivery_id |
| | 54 | ) |
| | 55 | SELECT |
| | 56 | it.invoice_id, |
| | 57 | it.comp_order_id, |
| | 58 | cmp.company_id, |
| | 59 | cmp.company_name, |
| | 60 | cmp.company_address, |
| | 61 | it.delivery_id, |
| | 62 | it.customer_order_count, |
| | 63 | it.invoice_amount, |
| | 64 | COALESCE(cc.contract_count, 0) AS contract_count |
| | 65 | FROM invoice_totals it |
| | 66 | JOIN kbnteam.company cmp ON cmp.company_id = it.company_id |
| | 67 | LEFT JOIN company_contracts cc ON cc.company_id = cmp.company_id; |
| | 68 | }}} |
| | 69 | |
| | 70 | == Тестирање на перформанси == |
| | 71 | |
| | 72 | === Препорачано тест прашање === |
| | 73 | {{{ |
| | 74 | #!sql |
| | 75 | SET search_path TO kbnteam; |
| | 76 | SET statement_timeout = '60s'; |
| | 77 | |
| | 78 | -- Тест 1: по компанија |
| | 79 | EXPLAIN (ANALYZE, BUFFERS, VERBOSE) |
| | 80 | SELECT * FROM kbnteam.v_company_billing_overview |
| | 81 | WHERE company_id = 1; |
| | 82 | |
| | 83 | -- Тест 2: по компаниска нарачка |
| | 84 | EXPLAIN (ANALYZE, BUFFERS, VERBOSE) |
| | 85 | SELECT * FROM kbnteam.v_company_billing_overview |
| | 86 | WHERE comp_order_id = 1; |
| | 87 | }}} |
| | 88 | |
| | 89 | === Резултати пред индексирање === |
| | 90 | ||= Метрика ||= Тест 1 (company_id) ||= Тест 2 (comp_order_id) || |
| | 91 | || Planning Time || ___ ms || ___ ms || |
| | 92 | || Execution Time || ___ ms || ___ ms || |
| | 93 | || Rows Returned || ___ || ___ || |
| | 94 | || contract scan || ___ || ___ || |
| | 95 | || customer_order scan || ___ || ___ || |
| | 96 | |
| | 97 | {{{ |
| | 98 | -- Излезот од EXPLAIN ANALYZE овде (пред индексирање) |
| | 99 | }}} |
| | 100 | |
| | 101 | === Применети индекси === |
| | 102 | {{{ |
| | 103 | #!sql |
| | 104 | -- indexes/v_company_billing_overview_index.sql |
| | 105 | CREATE INDEX IF NOT EXISTS idx_contract_company_id |
| | 106 | ON kbnteam.contract (company_id); |
| | 107 | |
| | 108 | CREATE INDEX IF NOT EXISTS idx_customer_order_comp_order_id |
| | 109 | ON kbnteam.customer_order (comp_order_id); |
| | 110 | }}} |
| | 111 | |
| | 112 | === Резултати по индексирање === |
| | 113 | ||= Метрика ||= Тест 1 (company_id) ||= Тест 2 (comp_order_id) || |
| | 114 | || Planning Time || ___ ms || ___ ms || |
| | 115 | || Execution Time || ___ ms || ___ ms || |
| | 116 | || Rows Returned || ___ || ___ || |
| | 117 | || contract scan || ___ || ___ || |
| | 118 | || customer_order scan || ___ || ___ || |
| | 119 | |
| | 120 | {{{ |
| | 121 | -- Излезот од EXPLAIN ANALYZE овде (по индексирање) |
| | 122 | }}} |
| | 123 | |
| | 124 | === Анализа на подобрување === |
| | 125 | ||= Индекс ||= Помага на ||= Очекувана промена || |
| | 126 | || `idx_contract_company_id` || CTE `company_contracts` GROUP BY || Seq Scan → Index Scan на `contract` || |
| | 127 | || `idx_customer_order_comp_order_id` || CTE `invoice_totals` LEFT JOIN || Seq Scan → Index Scan на `customer_order` || |
| | 128 | |
| | 129 | ||= Метрика ||= Пред ||= По ||= Δ Подобрување || |
| | 130 | || Execution Time (Тест 1) || ___ ms || ___ ms || ___ % || |
| | 131 | || Execution Time (Тест 2) || ___ ms || ___ ms || ___ % || |