Logo GH

PostgreSQL: best practices va indekslash

(Bo’lim: Texnologiyalar va infratuzilma)

Qisqacha xulosa

PostgreSQL - pul, KYC va iGaming’dagi yuridik ahamiyatga ega yozuvlar uchun «haqiqat yadrosi». U ACID kafolatlari, kuchli SQL va kengaytiruvchanlikni beradi. Turnirlar va PSP vebxuklarining eng yuqori cho’qqilariga bardosh berish uchun savodli sxema, indekslar, partiyalashtirish, avtovakuum, WAL tyuningi va kuzatish juda muhim. Quyida - amaliyot va shablon konstruktori.

1) Arxitektura va SLO

PostgreSQL roli: yozish uchun yetakchi + oʻqish uchun nusxalar; issiq ekranlar uchun - kesh/proyeksiya (Redis/materiallashtirilgan tomoshalar).
SLO misollar: p99’INSERT/UPDATE’hamyoni ≤ 25-40 ms; p99 balansni o’qish ≤ 10-15 ms; lag replik ≤ 2-5 s; foydalanish imkoniyati ≥ 99. 9%.
read-after-write siyosati: foydalanuvchi ekranlari tranzaksiyadan so’ng etakchidan o’qiladi yoki replikatsiya kechikishini kutadi.

2) Sxemalarni loyihalashtirish

Pul yadrosini normallashtirish (hamyonlar, ledger) + o’qish uchun denormallashtirish (CQRS/proyeksiyalar).
Qat’iy cheklovlar:’NOT NULL’,’CHECK’,’UNIQUE’, FK maqsadli’ON DELETE/UPDATE’(RESTRICT/SET NULL/NO ACTION).
Sxemani versionlash: up/down migratsiyasi, feature-bayroqlar; issiq vaqtda nomni oʻzgartirishdan qoching.
Identifikatorlar:’BIGINT’+ ketma-ketlik (yoki taqsimlanish uchun ULID/UUIDv7). Issiq qo’shimchalar uchun - alohida tablespace/WAL-jilddagi ketma-ketliklar.

3) Indeksatsiya: nima, qayerda va qanday

3. 1 B-Tree (defolt)

Qachon: aniq muvofiqliklar, diapazonlar, saralash, FK bo’yicha’JOIN’.
Patternlar:’WHERE player_id =?’,’ORDER BY created_at DESC LIMIT 100’.

Amaliyot:
  • Ko’p ustunli indekslar - shartlar tartibiga mos keling.
  • Covering: `INCLUDE (...)` для index-only scan.
  • Alohida indeks’ORDER BY... DESC’ning «lentalari».
sql
CREATE INDEX idx_tx_player_created_desc
ON tx (player_id, created_at DESC) INCLUDE (amount_cents, status);

3. 2 GIN (JSONB, massivlar, to’liq matn)

Qachon: JSONB - yo’l kalitlari, tag massivlari, FTS.
Variantlar:’gin _ trgm _ ops’,’jsonb _ path _ ops ’/’ jsonb _ ops’.
Amaliyot: qidiruv maydonlarini qat’iy cheklang va kardinallik haqida o’ylang.

sql
CREATE INDEX idx_profile_jsonb_gin
ON player_profile USING GIN (data jsonb_path_ops);

-- Search by email/name with typos
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX idx_player_trgm ON player USING GIN (email gin_trgm_ops);

3. 3 GiST (geo/diapazonlar/imzolar)

Qachon: geolokatsiya (IP-geo, radiuslar), intervallar, nearest-neighbor.
Pul yadrosida kamroq foydalaniladi, geo-cheklovlar/mas’uliyatli o’yin uchun foydalidir.

3. 4 BRIN (vaqt bo’yicha katta appendiks)

Qachon: milliardlab satrlar, vaqt boʻyicha tabiiy korrelyatsiya (stavkalar/voqealar jurnallari).
Afzalliklari: kichik o’lcham, arzon xizmat.
Kamchiliklar: qo’pol selektivlik → partiyalashtirish bilan birlashtirish.

sql
CREATE INDEX idx_bets_brin ON bets USING BRIN (created_at) WITH (pages_per_range = 64);

3. 5 Hash

Kamdan-kam hollarda: diapazonlar boʻlmaganda bir ustundan tenglik; koʻpincha B-Tree yetarli.

3. 6. Qisman va iboralar

Partial index: issiq kichik toʻplamlarni tezlashtiradi (aktiv,’status =’pending’).
Expression index: kalit (’lower (email)’,’(data->>’psp _ tx’)’).

sql
CREATE INDEX idx_withdraw_pending ON withdrawals (player_id)
WHERE status = 'pending';

CREATE INDEX idx_tx_psp_tx ON tx ((data->>'psp_tx'));

3. 7 Indekslarga qarshi

«Hamma narsa uchun indeks»: ortiqcha indekslar yozuvni sekinlashtiradi va VACUUM.
Takrorlanuvchi indekslar (xuddi shu ustunlar to’plami/tartibi).
Kardinalligi juda past bo’lgan ustunga indeks (masalan,’status’2 qiymatli) - qisman qiling.

4) Partiyalashtirish

Nima uchun: bloat qisqartirish, VACUUM/skanerlarni tezlashtirish, retention/arxivni osonlashtirish.
Sxemalar: stavkalar daftarlari uchun sana (kun/hafta) bo’yicha RANGE; katta foydalanuvchi jadvallari uchun’player _ id’uchun HASH; kombinatsiyalangan holda.
Rotatsiya amaliyoti: kelgusi partiyalarni oldindan yaratish, «ATTACH PARTITION», eskilar arxivi - «DETACH» + koʻchirish.

sql
CREATE TABLE bets (
bet_id BIGINT PRIMARY KEY,
player_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
amount_cents BIGINT NOT NULL
) PARTITION BY RANGE (created_at);

CREATE TABLE bets_2025_11_05 PARTITION OF bets
FOR VALUES FROM ('2025-11-05') TO ('2025-11-06');

5) Minimal parchalanishga ega bo’lgan qo’shimchalar/yangilanishlar

HOT-yangilanishlar:’fillfactor’ni (masalan, 90) sahifadagi boʻsh joy uchun issiq jadvallarda saqlang.
TOAST: katta JSONB/matnlar - ixchamlashtirishni kuzating; katta maydonlarni alohida jadvalda saqlang.
UPSERT:’ON CONFLICT’dan foydalaning... DO UPDATE’idempotent mantiqqa ega.

sql
INSERT INTO wallet (player_id, balance_cents, updated_at)
VALUES ($1, $2, now())
ON CONFLICT (player_id) DO UPDATE
SET balance_cents = wallet. balance_cents + EXCLUDED. balance_cents,
updated_at = now();

6) Tranzaksiyalar, blokirovkalar va raqobat

Izolyatsiya darajalari: aksariyat yo’llar uchun’READ COMMITTED’;’REPEATABLE READ ’/’ SERIALIZABLE’nuqtali (hisobotlar, oflayn-batchi). Ularni uzoq tutmang.
Bloklash turlari: row-level (pessimizm’FOR UPDATE’), table-level (DDL), taqsimlangan myutekslar uchun advisory locks.
Deadlocks: qisqa tranzaksiyalar, mavjudotlarni yangilashning yagona tartibi, taymautlar (’lock _ timeout’,’statement _ timeout’).
Vazifa navbatlari:’SKIP LOCKED’taqsimlangan vork-hovuz uchun.

sql
-- batch processor removes work without racing
SELECT id FROM jobs
WHERE status='pending'
FOR UPDATE SKIP LOCKED
LIMIT 100;

7) Avtovokum, statistika va bloat

VACUUM/ANALYZE: dolzarb statistikani (’default _ statistics _ target’) saqlang, issiq jadvallarda AVni sozlang (ishga tushirish chegarasi quyida).
wraparound (age (txid) <2 mlrd),’vacuum _ freeze _ min _ age’.
bloat-nazorat: og’ir indekslarda cho’qqidan tashqarida muntazam reindex/CLUSTER; partizanlashtirish muammo ko’lamini pasaytiradi.

Siyosat namunasi (jadval moslamalari):
sql
ALTER TABLE tx SET (
autovacuum_vacuum_scale_factor = 0. 05,
autovacuum_analyze_scale_factor = 0. 02,
autovacuum_vacuum_cost_limit = 4000
);

8) Xotira, chekpindlar va WAL

Xotira

’shared _ buffers’: 20-25% RAM (profilga bogʻliq).
’work _ mem’: amalda! Hisobot rollari uchun konservativ (masalan, 8-64MB) va nuqta darajasini oshiring.
’maintenance _ work _ mem’: katta indekslar/tiklash (vazifa boʻyicha 512MB-2GB).

WAL va chekpindlar

WAL uchun NVMe, alohida jild;’wal _ compression = on’.
’checkpoint _ timeout’ 10-15 min.,’max _ wal _ size’oʻzgarishlar hajmi ostida,’checkpoint _ completion _ target ≈ 0. 9`.
Qo’shimchalarning cho’qqilari uchun - batch qo’shimchalar va guruh kommitlari.

9) Replikatsiya va nosozlikka chidamlilik

Yetakchi replikalar: RPO ≈ 0-30s uchun eng yaqin (semi-sync) ga sinxron; o’qish/tahlillar uchun asinxron.
Promoushen va fencing: Patroni/replika-menejer; chiqarib tashlansin.
Hot standby:’hot _ standby _ feedback’ehtiyotkorlik bilan (bloat o’sishi), yaxshiroq - replikalarda uzoq tranzaksiyalarni singdiring.

10) Bekaplar va PITR

To’liq + inkremental bekap, ofsayt nusxalari; WAL uchun’archive _ command’.
PITR: stendlardagi vaqt nuqtasiga qadar tiklanishni tekshiring; RPO/RTOni tartibga soling (hamyonlar - daqiqalar, loglar - o’nlab daqiqalar).
DR (game day) mashqlari: qayta tiklashni muntazam tekshirish.

11) JSONB va «egiluvchan sxema» modeli

JSONB - kamdan-kam o’qiladigan/o’zgaruvchan atributlar uchun juda yaxshi (KYC-meta ma’lumotlar, PSP parametrlari).
Relatsiya ustunlaridagi majburiy maydonlarni qat’iy tasdiqlang; JSONB - nuanslarning «dumi» uchun.
Indeksatsiya: foydalaniladigan yoʻllar boʻyicha nuqtaviy GIN; «hamma narsaga bitta gigant GIN» dan qoching.

sql
-- partial GIN index only for documents with the desired key
CREATE INDEX idx_kyc_docnum ON kyc USING GIN ((data->'doc'->'number'))
WHERE data? 'doc';

12) To’liq matn va fuzzy-qidiruv

Oʻrnatilgan FTS:’tsvector’+ GIN; xatolar uchun -’pg _ trgm’.
Og’ir loglar/o’yinlar bo’yicha qidirish uchun - qidiruv tizimiga (ES/OpenSearch) olib kirish, PG’da esa havolani/meta ma’lumotlarni saqlash.

13) Kuzatish va profillash

pg_stat_statements: top sekin/tez-tez so’rovlar, normallashtirish.
EXPLAIN (ANALYZE, BUFFERS): rejalarni o’qing, issiq yo’llarda seq scan qidiring.
Metriklar: TPS, p95/p99, chekpindlar,’replication _ lag’, deadlocks, bloat, AV-tsikllar, cache-hit ≥ 95%.
Alertlar: laglarning o’sishi, «idle in transaction», kutilmagan seq scan, WAL-bo’ron.

14) Ulanishlar puli va tayyorlangan so’rovlar

Puller (PgBouncer)’transaction’rejimida veb-trafik uchun;’session’- uzoq kursorlar/bek-ofis uchun.
Prepared statements/parametrlash → kamroq parsing, barqaror rejalar.
Bekendlarning maksimal sonini cheklang (’max _ connections’past; ).

15) Xavfsizlik va komplayens

Tranzitdagi TLS, disklarni shifrlash, KMS/tashqi kalitlar.
RBAC: minimal huquqlar, rollarni ajratish o’qish/yozish/admin.
Ko’p tenant ssenariylar uchun RLS (Row-Level Security).
PII: niqoblash/taxalluslashtirish, saqlash muddati.
Audit:’pgaudit ’/tanqidiy jadvallardagi audit triggerlari (hamyon/ledger).

16) iGaming uchun namunaviy namunalar

16. 1 Hamyon va ledger (qat’iy muvofiqlik)

Индексы: `wallet(player_id PK)`, `ledger(player_id, ts DESC)` + `INCLUDE (delta_cents, reason)`.
Tranzaksiya balansni yangilaydi va ledger-ga yozadi; semi-sync replikatsiyasi; kesh faqat proyeksiya sifatida.

16. 2 Stavkalar tarixi (yuqori TPS, o’yinchi/vaqt bo’yicha o’qish)

Kun/hafta bo’yicha partiyalashtirish, vaqt bo’yicha BRIN + B-Tree’(player_id, created_at DESC)’.
’DETACH PARTITION’ orqali Retenshn → OLAP arxivlash.

16. 3 PSP vebxuklari (burstami, retrai)

«Xom» voqealar navbati (append-only), vaqt bo’yicha partiyalar, qisman indeks’status =’pending’bo’yicha.
Idempotentlik’idempotency _ key ’/’ psp _ tx’(UNIQUE).

17) Joriy etish chek-varaqasi

1. SLO va read-after-write siyosatini tuzating.
2. Haqiqiy soʻrovlar uchun asosiy indekslarni loyihalashtiring.
3. Retenshn/append-patternlar mavjud bo’lgan joyda partiyalashtirishni yoqing.
4. Issiq jadvallarda AV/ANALYZE moslamalarini oʻrnating, bloat/wraparound.
5. Xotira, WAL va chekpindlarni eng yuqori oynalar ostida sozlang.
6. Ulanish pulini & pg _ stat _ statements’; alerta qiling.
7. Replikatsiya + DR + PITR - majburiy; mashqlar o’tkazing.
8. JSONB va GINni faqat zarur yo’llar bilan cheklang; partial indexesdan foydalaning.
9. Bitimlarning davomiyligini minimallashtiring va’SKIP LOCKED’dan foydalaning.
10. Audit/PII/shifrlash/rol modeli - to’lovlar boshlangunga qadar.

18) Antipatternlar

Hamma narsaga bitta «universal» indeks va so’rovlar tahlili yo’q.
Uzoq «osilgan» tranzaksiyalar (’idle in transaction’) → blokirovka/bloat o’sishi.
Lag’dan tashqari read-after-write uchun replikalarga tayanish.
JSONB’da hamma narsani saqlash va butun hujjatni bitta GIN bilan indekslash.
VACUUM/ANALYZE nol nazorati va lag/chekpint monitoringi yo’qligi.
Eng yuqori soatlarda ommaviy migratsiya/DDL.

19) Foydali snippetlar

Soʻrov va bufer rejasi

sql
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT amount_cents
FROM ledger
WHERE player_id = $1
ORDER BY ts DESC
LIMIT 100;

«Ogʻir» soʻrovlarni profillash

sql
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;

Partiyalarni rotatsiya qilish (g’oya)

sql
-- create a party for tomorrow
CREATE TABLE bets_2025_11_06 PARTITION OF bets
FOR VALUES FROM ('2025-11-06') TO ('2025-11-07');

Yakunlar

PostgreSQL yuklamaning chiziqli o’sishi bilan iGaming platformasida «pul va haqiqat» ni tortishga qodir - agar indeks, partiya, avtovokum, WAL/xotira, replika/DR va kuzatish qobiliyati intizomli bo’lsa. So’rovlar profilidan va SLOdan boshlang, haqiqiy namunalar uchun indekslar tuzing, issiq jadvallarni izolyatsiya qiling, qat’iy foydalanish gigiyenasini yoqing - va baza turnirlar va eng yuqori to’lovlarni oldindan biladi.

Contact

Biz bilan bog‘laning

Har qanday savol yoki yordam bo‘yicha bizga murojaat qiling.Doimo yordam berishga tayyormiz.

Telegram
@Gamble_GC
Integratsiyani boshlash

Email — majburiy. Telegram yoki WhatsApp — ixtiyoriy.

Ismingiz ixtiyoriy
Email ixtiyoriy
Mavzu ixtiyoriy
Xabar ixtiyoriy
Telegram ixtiyoriy
@
Agar Telegram qoldirilgan bo‘lsa — javob Email bilan birga o‘sha yerga ham yuboriladi.
WhatsApp ixtiyoriy
Format: mamlakat kodi va raqam (masalan, +998XXXXXXXX).

Yuborish orqali ma'lumotlaringiz qayta ishlanishiga rozilik bildirasiz.