= Преглед: v_customer_loyalty_full_v2 = ||= Својство ||= Вредност || || Шема || `kbnteam` || || Категорија || Лојалност на клиентите || || Поврзани индекси || [wiki:CustomerLoyaltyFullIndex Индекси за лојалност на клиентите] || == Опис == Ги прикажува клиентот, компанијата, поените, статусот и нивото на лојалност, бројот на нарачки, вкупната потрошувачка и датумот на последната нарачка. Статистиката се пресметува по клиент и ги опфаќа сите статуси на нарачки. Се прикажуваат членовите на програмата за лојалност, вклучувајќи ги и оние без нарачки. Еден ред за секој член на програмата за лојалност. Кај член без нарачки бројот и потрошувачката се нула, а последната нарачка е NULL. == Зависности == ||= Табела / преглед ||= Употреба || || `kbnteam.customer_order` || Клиентски нарачки, датуми, статуси и износи. || || `kbnteam.customer_loyalty` || Членство и поени во програмата за лојалност. || || `kbnteam.customer` || Клиенти и компаниите на кои припаѓаат. || || `kbnteam.company` || Податоци за компаниите. || || `kbnteam.api_user` || Лични и контактни податоци за корисниците. || || `kbnteam.customer_loyalty_status` || Статуси на членството. || || `kbnteam.loyalty_tier` || Нивоа и поволности во програмата за лојалност. || == Излезни колони == ||= Колона ||= Извор / пресметка ||= Опис || || `cus_loyalty_id` || `customer_loyalty.cus_loyalty_id` || Идентификатор на членството. || || `customer_user_id` || `customer_loyalty.user_id` || Идентификатор на клиентот. || || `company_id` || `customer.company_id` || Идентификатор на компанијата. || || `company_name` || `company.company_name` || Назив на компанијата. || || `user_first_name` || `api_user.user_first_name` || Име на клиентот. || || `user_last_name` || `api_user.user_last_name` || Презиме на клиентот. || || `user_email` || `api_user.user_email` || Е-пошта на клиентот. || || `user_phone_no` || `api_user.user_phone_no` || Телефон на клиентот. || || `cus_loyalty_curr_points` || `customer_loyalty.cus_loyalty_curr_points` || Тековни поени за лојалност. || || `cus_loyalty_joined_at` || `customer_loyalty.cus_loyalty_joined_at` || Датум и време на зачленување. || || `cus_loyalty_status_id` || `customer_loyalty_status.cus_loyalty_status_id` || Идентификатор на статусот на членството. || || `cus_loyalty_status_name` || `customer_loyalty_status.cus_loyalty_status_name` || Назив на статусот на членството. || || `tier_id` || `loyalty_tier.tier_id` || Идентификатор на нивото. || || `tier_name` || `loyalty_tier.tier_name` || Назив на нивото. || || `tier_discount_percentage` || `loyalty_tier.tier_discount_percentage` || Процент на попуст. || || `tier_free_delivery_eligibility` || `loyalty_tier.tier_free_delivery_eligibility` || Право на бесплатна достава. || || `tier_priority_support` || `loyalty_tier.tier_priority_support` || Право на приоритетна поддршка. || || `order_count` || `COALESCE(order_stats.order_count, 0)` || Вкупен број на клиентски нарачки. || || `total_spent` || `COALESCE(order_stats.total_spent, 0)::numeric(14,2)` || Збир на износите на клиентските нарачки. || || `last_order_at` || `order_stats.last_order_at` || Датум и време на последната нарачка. || == SQL дефиниција == {{{ #!sql CREATE OR REPLACE VIEW kbnteam.v_customer_loyalty_full_v2 AS WITH order_stats AS ( SELECT o.customer_user_id, COUNT(*) AS order_count, SUM(o.order_total)::numeric(14,2) AS total_spent, MAX(o.order_datetime) AS last_order_at FROM kbnteam.customer_order o GROUP BY o.customer_user_id ) SELECT cl.cus_loyalty_id, cl.user_id AS customer_user_id, cu.company_id, cmp.company_name, au.user_first_name, au.user_last_name, au.user_email, au.user_phone_no, cl.cus_loyalty_curr_points, cl.cus_loyalty_joined_at, cls.cus_loyalty_status_id, cls.cus_loyalty_status_name, lt.tier_id, lt.tier_name, lt.tier_discount_percentage, lt.tier_free_delivery_eligibility, lt.tier_priority_support, COALESCE(os.order_count, 0) AS order_count, COALESCE(os.total_spent, 0)::numeric(14,2) AS total_spent, os.last_order_at FROM kbnteam.customer_loyalty cl JOIN kbnteam.customer cu ON cu.user_id = cl.user_id JOIN kbnteam.company cmp ON cmp.company_id = cu.company_id JOIN kbnteam.api_user au ON au.user_id = cl.user_id JOIN kbnteam.customer_loyalty_status cls ON cls.cus_loyalty_status_id = cl.cus_loyalty_status_id JOIN kbnteam.loyalty_tier lt ON lt.tier_id = cl.tier_id LEFT JOIN order_stats os ON os.customer_user_id = cl.user_id; }}} == Тестирање на перформанси == Мерењата се евидентирани во DBeaver на 14 септември 2026 година. „Пред индексирање“ и „по индексирање“ ги означуваат групите наведени како „без индекси“ и „со индекси“ во евиденцијата. Точниот сет присутни индекси во секоја група не е евидентиран; „без индекси“ не потврдува отсуство на индекси од примарни и уникатни клучеви. Наведените времиња се клиентски мерења од DBeaver, а не серверските Planning Time и Execution Time од EXPLAIN ANALYZE. Нема приложени планови, типови на скенирање или податоци за баферите. Вредностите се во милисекунди (ms). === Измерен прашалник === {{{ #!sql SELECT * FROM kbnteam.v_customer_loyalty_full_v2 WHERE customer_user_id = 500000; }}} === Резултати пред индексирање === ||= Метрика ||= Измерен резултат || || Клиентско време (ms) || 687 || || Приказ на мерењето || Време прикажано со резултатот во DBeaver || || Прикажани / преземени редови || 1 || || Planning Time / Execution Time од EXPLAIN || Не се измерени || || План, тип на скенирање и бафери || Не се приложени || === Дополнителни и заеднички индекси === `customer_loyalty(user_id)` има уникатен индекс. Индексот по клиент и датум не го содржи order_total, па пресметката на вкупната потрошувачка и натаму бара читање на износите. ||= Индекс ||= Табела и колони ||= Намена || || `idx_customer_order_customer_user_id_order_datetime` || `customer_order(customer_user_id, order_datetime DESC)` || Пронаоѓање нарачки по клиент; поддршка за пристап по датум во рамки на клиентот. || || `idx_customer_company_id` || `customer(company_id)` || Пронаоѓање клиенти по компанијата на која припаѓаат. || {{{ #!sql CREATE INDEX IF NOT EXISTS idx_customer_order_customer_user_id_order_datetime ON kbnteam.customer_order (customer_user_id, order_datetime DESC); CREATE INDEX IF NOT EXISTS idx_customer_company_id ON kbnteam.customer (company_id); }}} === Проверка на индексите === {{{ #!sql SELECT tablename, indexname, indexdef FROM pg_indexes WHERE schemaname = 'kbnteam' AND indexname IN ( 'idx_customer_order_customer_user_id_order_datetime', 'idx_customer_company_id' ) ORDER BY tablename, indexname; }}} === Резултати по индексирање === ||= Метрика ||= Измерен резултат || || Клиентско време (ms) || 66 || || Приказ на мерењето || Време прикажано со резултатот во DBeaver || || Прикажани / преземени редови || 1 || || Planning Time / Execution Time од EXPLAIN || Не се измерени || || План, тип на скенирање и бафери || Не се приложени || === Анализа на резултатите === ||= Метрика ||= Пред ||= По ||= Промена на времето || || Клиентско време (ms) || 687 || 66 || -90,4% || Времето е пократко за 621 ms (90,4%), приближно 10,4 пати. Резултатот се однесува на пристап по конкретен клиент; не го потврдува истиот ефект за пребарување по компанија, ниво или за целосен преглед. Промената се пресметува како 100 × (време по - време пред) / време пред. Негативна вредност значи пократко време, а позитивна подолго време. Процентот ја опишува разликата меѓу прикажаните вредности. Ова се поединечни набљудувања. Не се евидентирани контролирани повторувања, исти услови за кеширање и оптоварување или точните дефиниции на присутните индекси. Затоа промената на времето не е доказ дека индексите се единствената причина. Не се приложени мерења за INSERT, UPDATE и DELETE. === Дополнително тестирање - сè уште неизмерено === Следниот прашалник служи за ново мерење на серверскиот план со истиот филтер. Неговите резултати не се пополнети со клиентските времиња наведени погоре. За споредба се задржуваат исти податоци и поставки, се евидентираат присутните индекси, се ажурираат статистиките и се прават повеќе повторувања во двете состојби. Се споредуваат медијаната на времињата и плановите. {{{ #!sql BEGIN READ ONLY; SET LOCAL statement_timeout = '60s'; EXPLAIN (ANALYZE, BUFFERS, VERBOSE) SELECT * FROM kbnteam.v_customer_loyalty_full_v2 WHERE customer_user_id = 500000; ROLLBACK; }}} ||= Метрика за дополнителното тестирање ||= Пред ||= По || || Planning Time (ms) || Не е измерено || Не е измерено || || Execution Time (ms) || Не е измерено || Не е измерено || || Тип на скенирање по табела || Не е евидентиран || Не е евидентиран || || Shared Hit Blocks / Shared Read Blocks || Не се измерени || Не се измерени ||