|
| 1 | +-- explain_analyze_indexes.sql |
| 2 | +-- Measures query execution time before and after adding the analytics indexes. |
| 3 | +-- |
| 4 | +-- Usage: |
| 5 | +-- 1. Run the BEFORE blocks BEFORE applying the migration (drop indexes if needed). |
| 6 | +-- 2. Apply 001_create_events_table.sql |
| 7 | +-- 3. Run the AFTER blocks and compare Planning/Execution times. |
| 8 | +-- |
| 9 | +-- Requires: a populated `events` table with representative data. |
| 10 | +-- Tip: seed with at least 100k rows for meaningful results. |
| 11 | + |
| 12 | +-- ─── Seed helper (optional) ─────────────────────────────────────────────────── |
| 13 | +-- INSERT INTO events (group_id, member_address, event_type, amount, cycle, |
| 14 | +-- ledger_sequence, transaction_hash, created_at) |
| 15 | +-- SELECT |
| 16 | +-- (random() * 999 + 1)::BIGINT, |
| 17 | +-- 'G' || substr(md5(random()::text), 1, 55), |
| 18 | +-- (ARRAY['ContributionMade','PayoutExecuted','MemberJoined','GroupCreated'])[ceil(random()*4)::int], |
| 19 | +-- (random() * 10000)::NUMERIC(20,7), |
| 20 | +-- (random() * 11 + 1)::INTEGER, |
| 21 | +-- (random() * 1000000)::BIGINT, |
| 22 | +-- md5(random()::text), |
| 23 | +-- NOW() - (random() * INTERVAL '365 days') |
| 24 | +-- FROM generate_series(1, 100000); |
| 25 | + |
| 26 | +-- ───────────────────────────────────────────────────────────────────────────── |
| 27 | +-- QUERY 1: Cycle analytics (group_id, event_type, created_at) |
| 28 | +-- ───────────────────────────────────────────────────────────────────────────── |
| 29 | + |
| 30 | +-- BEFORE (sequential scan expected without index) |
| 31 | +EXPLAIN ANALYZE |
| 32 | +SELECT group_id, event_type, created_at, amount, cycle |
| 33 | +FROM events |
| 34 | +WHERE group_id = 42 |
| 35 | + AND event_type = 'ContributionMade' |
| 36 | + AND created_at >= NOW() - INTERVAL '30 days' |
| 37 | +ORDER BY created_at DESC; |
| 38 | + |
| 39 | +-- AFTER (index scan expected on idx_events_cycle_analytics) |
| 40 | +-- Run the same query again after migration — output should show: |
| 41 | +-- "Index Scan using idx_events_cycle_analytics on events" |
| 42 | +EXPLAIN ANALYZE |
| 43 | +SELECT group_id, event_type, created_at, amount, cycle |
| 44 | +FROM events |
| 45 | +WHERE group_id = 42 |
| 46 | + AND event_type = 'ContributionMade' |
| 47 | + AND created_at >= NOW() - INTERVAL '30 days' |
| 48 | +ORDER BY created_at DESC; |
| 49 | + |
| 50 | +-- ───────────────────────────────────────────────────────────────────────────── |
| 51 | +-- QUERY 2: Member history (member_address, event_type) |
| 52 | +-- ───────────────────────────────────────────────────────────────────────────── |
| 53 | + |
| 54 | +-- BEFORE (sequential scan expected without index) |
| 55 | +EXPLAIN ANALYZE |
| 56 | +SELECT member_address, event_type, created_at, amount, group_id |
| 57 | +FROM events |
| 58 | +WHERE member_address = 'GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5' |
| 59 | + AND event_type = 'PayoutExecuted' |
| 60 | +ORDER BY created_at DESC; |
| 61 | + |
| 62 | +-- AFTER (index scan expected on idx_events_member_history) |
| 63 | +-- Run the same query again after migration — output should show: |
| 64 | +-- "Index Scan using idx_events_member_history on events" |
| 65 | +EXPLAIN ANALYZE |
| 66 | +SELECT member_address, event_type, created_at, amount, group_id |
| 67 | +FROM events |
| 68 | +WHERE member_address = 'GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5' |
| 69 | + AND event_type = 'PayoutExecuted' |
| 70 | +ORDER BY created_at DESC; |
0 commit comments