Changes between Version 1 and Version 2 of otherdevelopment


Ignore:
Timestamp:
05/07/26 16:06:03 (3 days ago)
Author:
233062
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • otherdevelopment

    v1 v2  
    22
    33== Анализа на перформанси ==
     4
     5
     6=== Извештај за годишна финансиска активност на корисници ===
     7
     8Анализата на перформанси се врши врз основа на моменталната состојба во базата, која има податоци кои служат за тестирање. Базата содржи: ~1000 корисници, ~2000 приходи (incomes), ~1000 finance профили.
     9
     10SQL:
     11
     12{{{
     13SELECT
     14    fb.user_id,
     15    fb.username,
     16    fb.email,
     17    COALESCE(ai.income_count, 0) AS income_count,
     18    COALESCE(ai.annual_total_income, 0) AS annual_total_income,
     19    COALESCE(ma.active_months, 0) AS active_months,
     20    ROUND((COALESCE(ma.active_months, 0) / 12.0)::numeric, 4) AS activity_ratio,
     21    ROUND((COALESCE(fb.spending_budget, 0) / 100.0) * COALESCE(ai.annual_total_income, 0), 2) AS spending_amount,
     22    ROUND((COALESCE(fb.saving_budget, 0) / 100.0) * COALESCE(ai.annual_total_income, 0), 2) AS saving_amount,
     23    ROUND((COALESCE(fb.investing_budget, 0) / 100.0) * COALESCE(ai.annual_total_income, 0), 2) AS investing_amount,
     24    ROUND((COALESCE(fb.donation_budget, 0) / 100.0) * COALESCE(ai.annual_total_income, 0), 2) AS donation_amount,
     25    ROUND((COALESCE(fb.credit, 0) / 100.0) * COALESCE(ai.annual_total_income, 0), 2) AS credit_amount
     26FROM finance_users fb
     27LEFT JOIN (
     28    SELECT user_id, COUNT(*) AS income_count, SUM(amount) AS annual_total_income
     29    FROM incomes
     30    WHERE EXTRACT(YEAR FROM date) = 2026
     31    GROUP BY user_id
     32) ai ON ai.user_id = fb.user_id
     33LEFT JOIN (
     34    SELECT user_id, COUNT(DISTINCT EXTRACT(MONTH FROM date)) AS active_months
     35    FROM incomes
     36    WHERE EXTRACT(YEAR FROM date) = 2026
     37    GROUP BY user_id
     38) ma ON ma.user_id = fb.user_id
     39ORDER BY annual_total_income DESC;
     40}}}
     41Индекси:
     42
     431.
     44
     45{{{
     46idx_incomes_user_date
     47CREATE INDEX idx_incomes_user_date ON incomes(user_id, date);
     48}}}
     49
     50Подобрување:
     51Index Scan наместо Seq Scan + подобро филтрирање по година
     52
     532.
     54{{{
     55idx_incomes_year
     56CREATE INDEX idx_incomes_year ON incomes ((EXTRACT(YEAR FROM date)));
     57}}}
     58
     59Подобрување:
     60Избегнува full table scan за годишен филтер
     61
     623.
     63{{{
     64
     65idx_incomes_covering
     66CREATE INDEX idx_incomes_covering ON incomes(user_id, date, amount);
     67
     68}}}
     69
     70Подобрување:
     71Direct lookup
     72
     73
     744.
     75{{{
     76CREATE UNIQUE INDEX users_pkey
     77ON users(user_id);
     78
     79}}}
     80
     81Подобрување:
     82Fast join
     83
     845.
     85{{{
     86CREATE INDEX idx_incomes_covering
     87ON incomes(user_id, date, amount);
     88
     89}}}
     90
     91Подобрување:
     92Index-only scan (без пристап до табелата)
     93
     94==SQL за анализа на брзината
     95
     96{{{
     97CREATE OR REPLACE FUNCTION test_finance_report()
     98RETURNS void AS $$
     99DECLARE
     100  start_time timestamptz;
     101  end_time timestamptz;
     102  duration int;
     103BEGIN
     104  start_time := clock_timestamp();
     105
     106  PERFORM *
     107  FROM (
     108      SELECT
     109          fb.user_id,
     110          COALESCE(ai.income_count, 0),
     111          COALESCE(ai.annual_total_income, 0),
     112          COALESCE(ma.active_months, 0)
     113      FROM finance_users fb
     114      LEFT JOIN (
     115          SELECT user_id, COUNT(*), SUM(amount)
     116          FROM incomes
     117          WHERE EXTRACT(YEAR FROM date) = 2026
     118          GROUP BY user_id
     119      ) ai ON ai.user_id = fb.user_id
     120      LEFT JOIN (
     121          SELECT user_id, COUNT(DISTINCT EXTRACT(MONTH FROM date))
     122          FROM incomes
     123          WHERE EXTRACT(YEAR FROM date) = 2026
     124          GROUP BY user_id
     125      ) ma ON ma.user_id = fb.user_id
     126  ) t;
     127
     128  end_time := clock_timestamp();
     129  duration := round(1000 * (extract(epoch FROM end_time) - extract(epoch FROM start_time)));
     130
     131  RAISE NOTICE 'Query executed in: % ms', duration;
     132END;
     133$$ LANGUAGE plpgsql;
     134
     135-- run 1: no indexes
     136SELECT test_finance_report();
     137
     138-- run 2: add idx_incomes_user_date
     139CREATE INDEX idx_incomes_user_date ON incomes(user_id, date);
     140ANALYZE incomes;
     141SELECT test_finance_report();
     142
     143-- run 3: add idx_incomes_year
     144CREATE INDEX idx_incomes_year ON incomes ((EXTRACT(YEAR FROM date)));
     145ANALYZE incomes;
     146SELECT test_finance_report();
     147
     148-- run 4: add covering index
     149CREATE INDEX idx_incomes_covering ON incomes(user_id, date, amount);
     150ANALYZE incomes;
     151SELECT test_finance_report();
     152
     153DROP FUNCTION test_finance_report();
     154}}}
     155
     156Сумарно:
     157Без индекси: ~61ms
     158Со индекси: ~25ms
     159Забрзување: ~2.4x
    4160
    5161== Безбедност и заштита ==