| Version 2 (modified by , 2 weeks ago) ( diff ) |
|---|
Преглед: v_contracts_revenue
| Својство | Вредност |
|---|---|
| Шема | kbnteam
|
| Категорија | Договори и приходи |
| Поврзани индекси | Индекси за договори и приходи |
Опис
За секој договор ги прикажува бројот на компаниски и клиентски нарачки и вкупниот приход за парот компанија–ресторан.
Статистиката ги опфаќа сите нарачки, независно од датумот и статусот на договорот или нарачката. Целиот износ на нарачката се брои кај секој вклучен ресторан. Договорите за истиот пар компанија–ресторан ја прикажуваат истата статистика.
Еден ред за секој договор. Нарачките без јадења и пијалоци немаат поврзан ресторан и не влегуваат во статистиката. Договорите без соодветни нарачки имаат нулти броеви и приход.
Зависности
| Табела / преглед | Употреба |
|---|---|
kbnteam.order_meal | Јадења вклучени во нарачките. |
kbnteam.meal | Јадења, цени и поврзаност со категорија и ресторан. |
kbnteam.order_drink | Пијалоци вклучени во нарачките. |
kbnteam.drink | Пијалоци, количини, цени и ресторан. |
kbnteam.customer_order | Клиентски нарачки, датуми, статуси и износи. |
kbnteam.company_order | Поврзување на компаниските нарачки со компанијата и доставата. |
kbnteam.contract | Договори меѓу компаниите и рестораните. |
kbnteam.company | Податоци за компаниите. |
kbnteam.restaurant | Податоци за рестораните. |
kbnteam.contract_status | Називи на статусите на договорите. |
Излезни колони
| Колона | Извор / пресметка | Опис |
|---|---|---|
contract_id | contract.contract_id | Идентификатор на договорот. |
company_id | company.company_id | Идентификатор на компанијата. |
company_name | company.company_name | Назив на компанијата. |
rest_id | restaurant.rest_id | Идентификатор на ресторанот. |
rest_name | restaurant.rest_name | Назив на ресторанот. |
contract_status_name | contract_status.contract_status_name | Статус на договорот. |
contract_start_date | contract.contract_start_date | Почетен датум на договорот. |
contract_end_date | contract.contract_end_date | Краен датум на договорот. |
company_order_count | COALESCE(contract_metrics.company_order_count, 0) | Број на различни компаниски нарачки. |
customer_order_count | COALESCE(contract_metrics.customer_order_count, 0) | Број на клиентски нарачки. |
total_revenue | COALESCE(contract_metrics.total_revenue, 0)::numeric(14,2) | Збир на износите за парот компанија–ресторан. |
SQL дефиниција
CREATE OR REPLACE VIEW kbnteam.v_contracts_revenue AS
WITH order_restaurants AS (
SELECT
om.order_id,
m.rest_id
FROM kbnteam.order_meal om
JOIN kbnteam.meal m ON m.meal_id = om.meal_id
UNION
SELECT
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(*) AS customer_order_count,
SUM(o.order_total)::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;
Тестирање на перформанси
Примерите користат илустративни идентификатори и датуми. За споредливи мерења се избираат вредности што постојат во базата и се задржуваат истите податоци, филтри, услови за кеширање и број на повторувања. Статистиките за табелите треба да бидат ажурирани во двете состојби.
Тест прашалници
BEGIN READ ONLY; SET LOCAL statement_timeout = '60s'; -- Тест 1: по компанија 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; ROLLBACK;
Резултати пред индексирање
Основната состојба ги задржува индексите на примарните клучеви и уникатните ограничувања. Останатите присутни индекси се евидентираат одделно. При споредба на заеднички индекси се користи истата почетна состојба за секој преглед.
| Метрика | Тест 1 (по компанија) | Тест 2 (по ресторан) |
|---|---|---|
| Planning Time | _ ms | _ ms |
| Execution Time | _ ms | _ ms |
| Rows Returned | _ | _ |
| Начин на читање по табела | _ | _ |
| Shared Hit Blocks | _ | _ |
| Shared Read Blocks | _ | _ |
-- Планови и резултати пред дополнителното индексирање:
Дополнителни и заеднички индекси
contract(company_id, rest_id) поддржува и услов само по company_id. Индексот со rest_id како прва колона ја поддржува другата насока на пребарување.
| Индекс | Табела и колони | Намена |
|---|---|---|
idx_company_order_company_id | company_order(company_id) | Пронаоѓање компаниски нарачки по компанија. |
idx_customer_order_comp_order_id | customer_order(comp_order_id) | Пронаоѓање клиентски нарачки по компаниска нарачка. |
idx_order_meal_order_id_meal_id | order_meal(order_id, meal_id) | Пристап до јадењата на нарачката и групирање по order_id. |
idx_order_drink_order_id_drink_id | order_drink(order_id, drink_id) | Пристап до пијалоците на нарачката и групирање по order_id. |
idx_contract_company_id_rest_id | contract(company_id, rest_id) | Пребарување договори по компанија и ресторан и групирање по компанија. |
idx_contract_rest_id_company_id | contract(rest_id, company_id) | Пронаоѓање договори почнувајќи од ресторан. |
CREATE INDEX IF NOT EXISTS idx_company_order_company_id ON kbnteam.company_order (company_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_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_contract_company_id_rest_id ON kbnteam.contract (company_id, rest_id); CREATE INDEX IF NOT EXISTS idx_contract_rest_id_company_id ON kbnteam.contract (rest_id, company_id);
Проверка на индексите
SELECT tablename, indexname, indexdef
FROM pg_indexes
WHERE schemaname = 'kbnteam'
AND indexname IN (
'idx_company_order_company_id',
'idx_customer_order_comp_order_id',
'idx_order_meal_order_id_meal_id',
'idx_order_drink_order_id_drink_id',
'idx_contract_company_id_rest_id',
'idx_contract_rest_id_company_id'
)
ORDER BY tablename, indexname;
Резултати по индексирање
Мерењето ги користи истите тест прашалници и услови како почетното мерење.
| Метрика | Тест 1 (по компанија) | Тест 2 (по ресторан) |
|---|---|---|
| Planning Time | _ ms | _ ms |
| Execution Time | _ ms | _ ms |
| Rows Returned | _ | _ |
| Начин на читање по табела | _ | _ |
| Shared Hit Blocks | _ | _ |
| Shared Read Blocks | _ | _ |
-- Планови и резултати по дополнителното индексирање:
Анализа на подобрување
| Метрика | Пред | По | Промена (%) |
|---|---|---|---|
| Execution Time (Тест 1) | _ ms | _ ms | _ % |
| Execution Time (Тест 2) | _ ms | _ ms | _ % |
Промената се пресметува како 100 × (време пред − време по) / време пред, кога почетното време е поголемо од нула. Негативна вредност означува побавно извршување.
Изборот меѓу секвенцијално читање, индексно читање и други планови зависи од обемот на податоците, селективноста на филтрите и статистиките. Индексите не гарантираат забрзување или отстранување на сортирањата и спојувањата. Плановите и времињата се утврдуваат со мерење.
