wiki:ContractsRevenueView

Version 1 (modified by 185022, 2 weeks ago) ( diff )

--

Преглед: v_contracts_revenue

Датотека views/05_contracts_revenue_view.sql
Шема kbnteam
Категорија Договори, Фактурирање и Верност
Поврзани индекси indexes/v_contracts_revenue_index.sql
Сложеност Висока — 2 CTE со UNION + агрегации

Опис

Резимира приход по компанија и ресторан под активни договори. Го користи CTE order_restaurants за да определи кој ресторан го послужил секој редослед преку UNION на order_meal и order_drink. Вториот CTE contract_metrics агрегира броеви на нарачки и вкупен приход. Важен преглед за финансиско известување.

Зависности

Табела Тип на употреба
kbnteam.contract Главна табела
kbnteam.company JOIN — компанија
kbnteam.restaurant JOIN — ресторан
kbnteam.contract_status JOIN — статус на договор
kbnteam.customer_order JOIN (CTE) — нарачки
kbnteam.company_order JOIN (CTE) — компаниски нарачки
kbnteam.order_meal JOIN (CTE, UNION) — оброци во нарачки
kbnteam.meal JOIN (CTE) — ресторан на оброкот
kbnteam.order_drink JOIN (CTE, UNION) — пијачи во нарачки
kbnteam.drink JOIN (CTE) — ресторан на пијачот

SQL Дефиниција

CREATE OR REPLACE VIEW kbnteam.v_contracts_revenue AS
WITH order_restaurants AS (
    SELECT DISTINCT
        om.order_id,
        m.rest_id
    FROM kbnteam.order_meal om
    JOIN kbnteam.meal m ON m.meal_id = om.meal_id

    UNION

    SELECT DISTINCT
        od.order_id,
        d.rest_id
    FROM kbnteam.order_drink od
    JOIN kbnteam.drink d ON d.drink_id = od.drink_id
),
contract_metrics AS (
    SELECT
        co.company_id,
        orr.rest_id,
        COUNT(DISTINCT co.comp_order_id) AS company_order_count,
        COUNT(DISTINCT o.order_id) AS customer_order_count,
        COALESCE(SUM(o.order_total), 0)::numeric(14,2) AS total_revenue
    FROM kbnteam.customer_order o
    JOIN kbnteam.company_order co ON co.comp_order_id = o.comp_order_id
    JOIN order_restaurants orr ON orr.order_id = o.order_id
    GROUP BY co.company_id, orr.rest_id
)
SELECT
    ct.contract_id,
    cmp.company_id,
    cmp.company_name,
    r.rest_id,
    r.rest_name,
    cs.contract_status_name,
    ct.contract_start_date,
    ct.contract_end_date,
    COALESCE(cm.company_order_count, 0) AS company_order_count,
    COALESCE(cm.customer_order_count, 0) AS customer_order_count,
    COALESCE(cm.total_revenue, 0)::numeric(14,2) AS total_revenue
FROM kbnteam.contract ct
JOIN kbnteam.company cmp ON cmp.company_id = ct.company_id
JOIN kbnteam.restaurant r ON r.rest_id = ct.rest_id
JOIN kbnteam.contract_status cs ON cs.contract_status_id = ct.contract_status_id
LEFT JOIN contract_metrics cm
    ON cm.company_id = ct.company_id
   AND cm.rest_id = ct.rest_id;

Тестирање на перформанси

Препорачано тест прашање

SET search_path TO kbnteam;
SET statement_timeout = '60s';

-- Тест 1: по компанија (тестира idx на contract)
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT * FROM kbnteam.v_contracts_revenue
WHERE company_id = 1;

-- Тест 2: по ресторан
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT * FROM kbnteam.v_contracts_revenue
WHERE rest_id = 1;

Резултати пред индексирање

Метрика Тест 1 (по company_id) Тест 2 (по rest_id)
Planning Time _ ms _ ms
Execution Time _ ms _ ms
Rows Returned _ _
contract scan _ _
order_meal scan _ _
customer_order scan _ _
-- Излезот од EXPLAIN ANALYZE овде (пред индексирање)

Применети индекси

-- indexes/v_contracts_revenue_index.sql
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);

CREATE INDEX IF NOT EXISTS idx_contract_company_id_rest_id
ON kbnteam.contract (company_id, rest_id);

Резултати по индексирање

Метрика Тест 1 (по company_id) Тест 2 (по rest_id)
Planning Time _ ms _ ms
Execution Time _ ms _ ms
Rows Returned _ _
contract scan _ _
order_meal scan _ _
customer_order scan _ _
-- Излезот од EXPLAIN ANALYZE овде (по индексирање)

Анализа на подобрување

Индекс Помага на Очекувана промена
idx_contract_company_id_rest_id JOIN-от во contract_metrics и главниот SELECT Seq Scan → Index Scan
idx_customer_order_comp_order_id JOIN со company_order во CTE Seq Scan → Index Scan
idx_order_meal_order_id_meal_id CTE order_restaurants UNION Seq Scan → Index Scan
idx_order_drink_order_id_drink_id CTE order_restaurants UNION Seq Scan → Index Scan
Метрика Пред По Δ Подобрување
Execution Time (Тест 1) _ ms _ ms _ %
Execution Time (Тест 2) _ ms _ ms _ %
Note: See TracWiki for help on using the wiki.