ანალიტიკური მოთხოვნების ოპტიმიზაცია
1) რატომ ოპტიმიზაცია (iGaming კონტექსტი)
ბიზნესის სიჩქარე: GGR/NET ანგარიშები, პროვაიდერები/თამაშები, RG/AML და მარკეტინგი p95 SLA.
ღირებულება: ნაკლები სკანირებული ბაიტი და საფარი $/მოთხოვნაზე დაბალია.
საიმედოობა: სტაბილური პიკის საათი, BI- ს „ყინვების“ არარსებობა.
მასშტაბი: ათობით ბრენდი/ბაზარი, მილიარდობით სტრიქონი, სიახლის წუთი.
2) დატვირთვის პროფილი და SLO
აღწერეთ მოთხოვნის „პირველი 90%“: ფანჯრები (7/28/90d), ფილტრები ('brand, country, provider, psp, status'), join's, JSON ატრიბუტები, ტოპ K და დაფასდა.
SLO მაგალითები: p95-1. 2 ს დაშბორდისთვის, scanned bytes - 256 MV/მოთხოვნა, freshness - 5 min.
3) გეგმების ანატომია: რა უნდა მოძებნოთ
Predicate/Projection pushdown: ფილტრები და სვეტების სია წყაროზე ეშვება.
Partition pruning & data skipping: დამატებითი ნაწილების/ფაილების მოწყვეტა (min-max/bloom/manifest).
Vectorized scan/late materialization: კითხვა JOIN/PROJECTECT- ის მიერ გადავადებულ სვეტებზე.
Join strategy: Broadcast Hash (BHJ), Sort-Merge (SMJ), Nested Loop (NLJ — избегать).
Spill & shuffle: გადატვირთვის მოცულობა და სრუტე დისკზე არის SLA- ს მთავარი მტერი.
Adaptive query execution: სტრატეგიის შეცვლა rantime- ში (BHJ - SMJ გადართვა, დინამიური კოალესი).
გეგმა უნდა აჩვენოს: რამდენი ბაიტი ვკითხულობთ, სად არის ზაფლიმი, რომელსაც ჩვენ ქეშირებთ.
4) წვეულებები, დახარისხება, მტევანი შემთხვევები
წვეულებები: 'date' + 1-2 წვდომის გაზომვები (მაგალითად, 'brand, country').
დახარისხება/კლასტერიზაცია: 'ORDER BY/CLUSTER BY/Z-order' ხშირი ფილტრებით/ჯოინებით ('provider, game _ id, occurred _ at').
რეკლამირება და კომპენსაცია: რეგულარული გადაადგილება მონაცემთა სკიპინგისთვის; ფაილების სამიზნე ზომა 128-1024 MB.
5) JOIN ნიმუშები
Broadcast Hash Join (BHJ): მცირე განზომილება (ასობით MB) - ფაქტობრივად broadcast.
sql
/ hint if engine supports/
SELECT /+ BROADCAST(dim_provider) /...
Sort-Merge Join (SMJ): დიდი ნაკრები, თავსებადი ძირითადი დახარისხება/მტევანი შემთხვევები - მინიმალური ქუდი.
Pre-join/denormalization: მოიტანეთ სტაბილური ატრიბუტები 'dim _' - დან ფაქტობრივ სურათამდე (მიღწევა/მათერიზებული ხედვა) - მინუს JOIN კრიტიკულ გზაზე.
Anti/semijoins: ჩაწერეთ 'NOT IN/EXISTS' აშკარა semi-/anti-join გეგმებში.
რადიკალური აფეთქების აღმოფხვრა: შეამოწმეთ გაზომვების გასაღების დუბლიკატები, გამოიყენეთ surrogate-keys.
6) ჯგუფი BY, დანაყოფები და წინსვლა
Rollup/Cube/Grouping Sets: ერთი ეტაპი რამდენიმე ერთეულის ნაცვლად.
sql
SELECT brand, country, DATE(ts) d, SUM(amount)
FROM gold. payments
WHERE ts >= NOW() - INTERVAL '7 days'
GROUP BY GROUPING SETS ((brand,country,d),(brand,d),(d));
მატერიალიზებული წარმოდგენები (MV )/პროექციები: 'payments _ 7d _ by _ brand _ psp', 'rounds _ 1d _ by _ provider _ game'.
Partial - Final agregation: მოდით, ძრავა ნაწილობრივ დააკავშიროთ workers (ადგილობრივი) და საბოლოო კოორდინატორზე.
Approximate: HLL 'COUNT (DISTINCT user)', Percentiles TDigest - მრავალჯერადი იაფი და საკმარისია BI- სთვის.
7) ფანჯრის ფუნქციები (სისუფთავე)
PARTITION BY ზუსტად მაღალი სელექციური კლავიშებით; ORDER BY - სვეტების დახარისხება.
შეცვალეთ მძიმე ფანჯრები პრე-აგრეგატებსა და semi-joins- ში, სადაც შესაძლებელია.
sql
-- Instead of window distinct
SELECT brand, COUNT() users
FROM (SELECT DISTINCT brand, user_id FROM gold. sessions WHERE d>=CURRENT_DATE-7) t
GROUP BY brand;
8) ფილტრები, პაგინაცია და TOP-K
ფილტრების რიგი არ არის მნიშვნელოვანი CBO- სთვის, მაგრამ შერჩევითი და ინდექსები/დახარისხება მნიშვნელოვანია.
LIMIT … WITH TIES/APPROX TOP-K - ამცირებს სკანირებას.
პაგინაცია: 'keyset pagination' ნაცვლად 'OFSET/LIMIT "დიდი ცხრილებისთვის.
sql
-- keyset
SELECT FROM t WHERE (date, id) > (:last_date,:last_id) ORDER BY date, id LIMIT 1000;
9) JSON/ნახევრად სტრუქტურირებული
ცხელი გზები სვეტებისკენ ('მოწყობილობები. os`, `psp. method`).
გამოიყენეთ ინვერსიული ინდექსები/GIN JSON ტრასებზე, თუ ძრავა მხარს უჭერს.
თავიდან აიცილეთ UDF ხაზები: უმჯობესია პროექცია ატრიბუტების გამოყოფით.
10) Approx და სიმულაცია
HLL/Theta Sketch: იაფი 'COUNT DISTINCT'.
TDigest/KLL: მათ შეაფასეს p95/p99 სრული ჯიშის გარეშე.
Reservoir/stratified sampling: ინტერაქტიული კვლევა და გადახედვა.
11) მეხსიერება, სრუტე და კონკარენსი
Spill-guard: მეხსიერების შეზღუდვები join/agg- ზე; სრუტეზე - შეამცირეთ batch/parallelism, გაზარდეთ დახარისხება გასაღები.
Concurrence & QoS: აუზები „ცხელი“ დაშბორდებისთვის და მძიმე ად-ჰოკისთვის; სკანის/დროის ლიმიტები; kill-switch „დავიწყებული“ მოთხოვნებისთვის.
Result cache/query cache: ჩართეთ BI შაბლონები განმეორებით, ინვალიდი სიახლის ნიშნით.
12) რეგრესიის ტესტები და „ორმაგი რქა“
შეინახეთ საცნობარო პროფილები (გეგმა/სკანირების ბაიტი/დრო) საუკეთესო N მოთხოვნებისთვის.
ინდექსების/მტევნების გამოშვებამდე - A/B პროგონი: შეადარეთ p95, scanned bytes, skipped share, shuffle.
შექმენით „fail-fast“ ბარიერები: თუ p95 გაიზარდა> X% - გამოტოვება.
13) დაკვირვება და SLO
SLI:- p50/p95/p99 latency, scanned bytes/query, skipped bytes %, files touched;
- shuffle bytes, spilled bytes, peak memory;
- cache hit-rate; Approx აგრეგატების accuracy.
ალერტები: scanned bytes- ის ზრდა, skipped shar- ის ვარდნა, ხშირი NLJ, სრუტე> ბარიერი.
14) კეისი iGaming (რეცეპტები)
14. 1 გადახდა/PSP: „უკმარისობის მწვერვალები“
WHERE: `ts BETWEEN now()-7d AND now()`, `brand,country,psp,status`.
წვეულება: დღე; ORDER/Z-order: `(brand,country,ts)`; bitmap: `psp,status`; bloom: `transaction_id`.
MV: `payments_7d_by_brand_psp(status)`.
შედეგი: p95-~ 1s, scanned bytes - 5-10 ×, ნულოვანი სრუტე.
14. 2 თამაშის რაუნდი: ტოპ K თამაშები/საათი
ORDER BY / cluster по `(provider, game_id, occurred_at)`; პროექტი წინამორბედებისთვის.
Approx Top-K + TDigest რაუნდის ხანგრძლივობისთვის.
შედეგი: ქვე-წამიანი გრაფიკა ცხელ ქეშზე.
14. 3 RG/AML: აქტიური შეზღუდვები
JSON 'reason' სვეტი; bitmap `rg_state`, `kyc_level`; ბოლო მდგომარეობით semi-join.
შედეგი: ანგარიში „30 დღეში“ - წამით, სრული სკანის გარეშე.
15) ჩეკის ოპტიმიზაციის სია (ყოველდღიური)
1. ტოპ N მოთხოვნებისა და მათი პროფილების შეგროვება (გეგმა/ბაიტი/შაფი).
2. დანაყოფები + შეთანხმებული დახარისხება/მტევანი შემთხვევები.
3. შემოწმება pushdown და projection pruning (მხოლოდ საჭირო სვეტები).
4. JOIN სტრატეგია: broadcast მცირე, დახარისხება SMJ- სთვის, არა NLJ.
5. წინამორბედი/MV ცხელი დაშბორებისთვის.
6. Approx იქ, სადაც დასაშვებია (distinct/percentiles/top-k).
7. JSON არის სვეტები ან/და ინვერსიული ინდექსები.
8. კომპაქტური/რეკლამირება; skipped bytes- ის მიზანი 70% -ია.
9. შედეგების ქეში და ცალკეული Concarrency აუზები.
10. მონიტორინგი: p95, scanned bytes, shuffle, spill, hit-rate.
16) შაბლონები (გამოსაყენებლად მზად)
16. 1 ოპტიმიზაციის პოლიტიკა (YAML)
yaml workload: bi_hot slo:
p95_latency_ms: 1200 scanned_bytes_max_mb: 256 skipped_bytes_share_min: 0. 70 storage:
partition_by: ["date"]
cluster_by: ["brand","country","occurred_at"]
indexes:
bloom: ["transaction_id","user_surrogate_id"]
bitmap: ["psp","status","rg_state"]
aggregation:
mv:
- name: mv_payments_7d_brand_psp window: "7d"
group_by: ["brand","psp","status"]
approx:
count_distinct: "hll"
percentile: "tdigest"
concurrency:
pools: {bi_hot: 50, adhoc: 10}
timeout_s: 120
16. 2 მოთხოვნის რეგრესიის ტესტი (ფსევდო-SQL)
sql
-- baseline: p95<=1200ms, scanned_bytes<=256MB
EXPLAIN ANALYZE
SELECT brand, psp, status, COUNT() cnt, SUM(amount) amt
FROM gold. payments
WHERE ts >= NOW() - INTERVAL '7 days'
AND brand =:brand AND country =:country
GROUP BY brand, psp, status;
16. 3 DISTINCT გადაწერა
sql
-- Bad: Heavy COUNT (DISTINCT user_id)
SELECT COUNT(DISTINCT user_id) FROM gold. sessions WHERE d>=CURRENT_DATE-7;
-- Better: HLL sketch/preaggregate
SELECT hll_union(user_hll) FROM agg. sessions_7d_user_hll WHERE d>=CURRENT_DATE-7;
16. 4 Keyset pagination
sql
SELECT
FROM gold. game_rounds
WHERE (occurred_at, round_id) > (:ts,:rid)
AND brand=:brand AND country=:country
ORDER BY occurred_at, round_id
LIMIT 1000;
17) ანტი შაბლონები
'შერჩევა' გაყიდვაში; jection pruning არარსებობა.
OFFSET მილიონობით ხაზის პაგინაცია.
COUNT DISTINCT ესკიზების გარეშე; გადაკეთდა სრული ხარისხით.
NLJ დიდ კომპლექტებში; JSON გამონათქვამების მიხედვით.
მცირე ნაწილები და მიმოფანტული ფაილები (მეტამონაცემების ქარიშხალი).
UDF სტრიქონები WHERE- ში, სვეტების მატერიალიზაციის ნაცვლად.
სტატისტიკის უგულებელყოფა/ANALYZE - ბრმა ოპტიმიზატორი და სრული სკანი.
რეგრესიული ტესტებისა და დაბრუნების ბარიერების არარსებობა.
18) გზის განხორციელების რუკა
0-30 დღე (MVP)
1. გაზომეთ ტოპ N მოთხოვნა და SLO/SLI ინსტალაცია.
2. წვეულებები თარიღით + დახარისხება/მტევანი შემთხვევები; ჩართეთ მონაცემები skipping/bloom.
3. ერთი MV გადახდის „ცხელ“ ანგარიშზე; HLL/TDigest в BI.
4. შეკითხვის ტყვიების გამიჯვნა, ნაკადის საკვების ჩართვა.
30-90 დღე
1. მძიმე ფანჯრების/JSON აღწერილობა წინასწარ აგრეგაცია/სვეტები.
2. Broadcast-join მცირე გაზომვები; SMJ დიდი; NLJ- ის აღმოფხვრა.
3. დაგეგმილია კომპაქტური და რეკლამირება; მანქანის გამაძლიერებელი გასაღებები.
4. დეგრადაციის დაკვირვება და ალერტები, A/B გეგმები, ავტო-გამოტოვება.
3-6 თვე
1. პროექციის კატალოგი/MV ვერსიით და SLA.
2. Approx ბირთვი distinct/percentile/top-k ყველა დაშბორდისთვის.
3. რეგრესიის ტესტებისა და ბიუჯეტების ერთიანი შაბლონები/მოთხოვნა.
4. JSON და UDF მუდმივი ჰიგიენა: მატერიალიზაცია და ინდექსები.
19) RACI
Data Platform (R): წვეულებები/კლასტერიზაცია/კომპაქტური, MV/პროექცია, ქეში, მონიტორინგი.
ანალიზები/BI (R): SQL გადაწერა, approx აგრეგატები, რეგრესიის ტესტები.
დომენის ობნერები (C): მოთხოვნები ჭრილობებისა და სიზუსტის შესახებ.
უსაფრთხოება/DPO (A/R): კონფიდენციალურობა/PII, დანაყოფების k ანონიმურობა.
SRE/Observability (C): SLO/Alerting, Concarrency და Capasity.
Finance (C): ბიუჯეტები $/თხოვნით და ეკონომიკური ეფექტით.
20) დაკავშირებული მონაკვეთები
ანალიტიკური საცავის ინდექსაცია, მონაცემთა სქემები და მათი ევოლუცია, მონაცემთა ვალიდაცია, DataOps პრაქტიკა, მონაცემთა კლასტერიზაცია, განზომილების შემცირება, API ანალიტიკოსები და მეტრიკა, MLOps: მოდელების ექსპლუატაცია.
შედეგი
მოთხოვნების ოპტიმიზაცია არ არის „ჯადოსნური ჰინტი“, არამედ სისტემა: მონაცემთა კომპეტენტური აღნიშვნა (წვეულება/კლასტერები), წინასწარი აგრეგაცია და approximate ალგორითმები, სწორი JOIN სტრატეგიები, ქეში/concarrency და მუდმივი მონიტორინგი p95 და scanned bytes. IGaming- ისთვის, ეს ნიშნავს სწრაფი და სტაბილური გადახდის, თამაშებისა და შესაბამისობის მეტრებს - როგორც SLA და ბიუჯეტის ნაწილი.