Index turlari — B-tree, Hash, GIN, GiST, BRIN

~25 daq · PostgreSQL · Index va Performance

Million qator bor. WHERE email = 'jasur@mail.com' so'rovi bajariladi — PostgreSQL barcha million qatorni ko'rib chiqadi. Bu Seq Scan — ketma-ket o'qish. Natija 3 soniyada keladi.

Index qo'shilsa:

CREATE INDEX ON foydalanuvchilar (email);

Endi bir xil so'rov 2 millisekundda. Index — kitob oxiridagi ko'rsatkich: sahifani qidirish o'rniga, ko'rsatkich orqali to'g'ri o'tish.


B-tree — standart index

PostgreSQL da CREATE INDEX deganda B-tree (Balanced tree) yaratiladi. Ko'pchilik holatlar uchun mos.

CREATE INDEX idx_email ON foydalanuvchilar (email);

Qachon ishlaydi:

WHERE email = 'jasur@mail.com'    -- tenglik
WHERE yosh > 18                   -- taqqoslash (<, >, <=, >=)
WHERE yosh BETWEEN 18 AND 30      -- oraliq
WHERE ism LIKE 'Ali%'             -- prefiks (% oxirda)
ORDER BY email                    -- tartiblash

Qachon ishlamaydi:

WHERE ism LIKE '%Ali%'  -- % boshda — to'liq skan kerak
WHERE LOWER(email) = .. -- funksiya ichida — functional index kerak

Hash index

Faqat tenglik (=) uchun. B-tree dan tezroq — lekin faqat = bilan:

CREATE INDEX idx_email_hash ON foydalanuvchilar USING HASH (email);
WHERE email = 'jasur@mail.com' -- ✅ tez
WHERE email LIKE 'jasur%'      -- ❌ ishlamaydi
WHERE email > 'a'              -- ❌ ishlamaydi

Amalda kamdan-kam ishlatiladi — B-tree ko'pincha yetarli.


GIN — massiv va JSONB uchun

Generalized Inverted Index. Massiv elementlari va JSONB kalitlari bo'yicha qidirish uchun:

CREATE INDEX idx_teglar ON mahsulotlar USING GIN (teglar);
-- teglar — text[] massiv

CREATE INDEX idx_meta ON mahsulotlar USING GIN (meta);
-- meta — jsonb ustun
WHERE teglar @> ARRAY['elektronika']   -- massiv ichida bor
WHERE meta @> '{"faol": true}'         -- jsonb ichida bor

Full-text search uchun ham GIN:

CREATE INDEX idx_fts ON maqolalar USING GIN (to_tsvector('russian', matn));

GiST — geometrik va range uchun

Generalized Search Tree. Geometrik ma'lumotlar (PostGIS), range turlar, full-text uchun:

CREATE INDEX idx_joy ON joylar USING GIST (koordinata);
-- PostGIS geometrik qidiruv

CREATE INDEX idx_sana_oralig ON bandliklar USING GIST (sana_oralig);
-- daterange, tsrange

BRIN — katta ketma-ket jadvallar uchun

Block Range INdex. Juda kichik index — katta jadvallarda fizik tartibli ustunlar uchun:

CREATE INDEX idx_sana ON voqealar USING BRIN (yaratilgan);

Log jadvali kabi — yangi yozuvlar har doim oxirga qo'shilsa va sana bo'yicha qidirish kerak bo'lsa. Indeks hajmi juda kichik, lekin aniqlik kamroq.


Qaysi index turini tanlash?

Holat                              Index turi
─────────────────────────────────  ──────────
Tenglik, oraliq, tartiblash        B-tree (standart)
Faqat tenglik, yuqori yozuv        Hash
Massiv, JSONB, full-text           GIN
Geometriya, range                  GiST
Katta, ketma-ket, sana ustuni      BRIN

Tez-tez uchraydigan xatolar

Har ustinga index qo'yish:

Index yozuv kiritishni sekinlashtiradi — har yozuvda index yangilanadi. Faqat WHERE, JOIN, ORDER BY da ishlatilgan ustunlarga index.

LIKE '%matn%' uchun oddiy index:

CREATE INDEX ON mahsulotlar (nomi);
WHERE nomi LIKE '%noutbuk%'; -- ❌ index ishlamaydi, % boshda

Yechim — pg_trgm extension va GIN index (keyingi darslarda).


Xulosa

B-tree   — standart, ko'pchilik holat (=, <, >, BETWEEN, LIKE 'x%')
Hash     — faqat tenglik (=), kamdan-kam kerak
GIN      — massiv @>, JSONB @>, full-text search
GiST     — geometriya, range turlar
BRIN     — katta ketma-ket jadvallar, sana ustuni
CREATE INDEX               ON jadval (ustun);        -- B-tree
CREATE INDEX ... USING HASH ON jadval (ustun);       -- Hash
CREATE INDEX ... USING GIN  ON jadval (ustun);       -- GIN
CREATE INDEX ... USING GIST ON jadval (ustun);       -- GiST
CREATE INDEX ... USING BRIN ON jadval (ustun);       -- BRIN

Keyingi dars

38-dars: Composite Index, Partial Index, Covering Index