13-bo‘lim

Indekslar va so'rov optimizatsiyasi

Indeks qanday ishlaydi, turlari, tarkibiy indekslar, EXPLAIN o'qish va sekin so'rovlarni tezlashtirish.

🕑 12 daqiqa o‘qish 📄 912 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Indeks nima?
  2. Farqni o'lchash
  3. Indeks turlari
  4. Qaysi ustunlarga indeks kerak?
  5. Tarkibiy indekslar
  6. Indeksni buzadigan so'rovlar
  7. EXPLAIN - so'rovni tahlil qilish
  8. Muhim ustunlar
  9. type qiymatlari - yaxshidan yomonga
  10. Extra ustunidagi ogohlantirishlar
  11. Qoplovchi indeks (covering index)
  12. To'liq matnli qidiruv
  13. Sekin so'rovlarni topish
  14. Optimizatsiya ro'yxati
  15. Amaliy misol
  16. Xulosa

Indeks - bazani yuzlab barobar tezlashtiradigan yagona eng muhim vosita.

Indeks nima? #

Kitobning oxiridagi alifbo ko'rsatkichini tasavvur qiling. "Algoritm" so'zini topish uchun:

UsulAmal
Indekssiz500 sahifani birma-bir varaqlash
Indeks bilanKo'rsatkichdan "Algoritm - 42-bet" ni topish

Bazada ham xuddi shunday.

SQL
-- Indekssiz: butun jadval o'qiladi (full table scan)
SELECT * FROM talabalar WHERE email = '[email protected]';

-- Indeks yaratamiz
CREATE INDEX idx_email ON talabalar (email);

-- Endi: to'g'ridan-to'g'ri topiladi
SELECT * FROM talabalar WHERE email = '[email protected]';
B-daraxt indeksi: 1 000 000 qatordan 3 qadamda topish M D | H R | V Aziza... Husanboy Sardor... Zufar... Har qadamda qidiruv maydoni bir necha barobar qisqaradi Bu 15-bo'limda ko'rgan ikkilik qidiruvning kengaytirilgan shakli
Indeks B-daraxt tuzilmasida saqlanadi - qidiruv O(log n)

Farqni o'lchash #

SQL
-- 1 000 000 qatorli jadvalda
SELECT * FROM loglar WHERE foydalanuvchi_id = 12345;
HolatO'qilgan qatorlarVaqt
Indekssiz1 000 000~850 ms
Indeks bilan~20~2 ms

400 barobar farq.

Indeks turlari #

SQL
-- Oddiy indeks
CREATE INDEX idx_shahar ON talabalar (shahar);

-- Noyob indeks (takrorlanishga yo'l qo'ymaydi)
CREATE UNIQUE INDEX uq_email ON talabalar (email);

-- Tarkibiy (bir necha ustun)
CREATE INDEX idx_shahar_baho ON talabalar (shahar, ortacha_baho);

-- To'liq matnli qidiruv
CREATE FULLTEXT INDEX ft_matn ON maqolalar (sarlavha, matn);

-- Jadval yaratishda
CREATE TABLE talabalar (
    id     INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    email  VARCHAR(190) NOT NULL,
    shahar VARCHAR(60),

    UNIQUE KEY uq_email (email),
    KEY idx_shahar (shahar)
) ENGINE=InnoDB;

-- Ko'rish va o'chirish
SHOW INDEX FROM talabalar;
DROP INDEX idx_shahar ON talabalar;
PRIMARY KEY avtomatik indeks

Birlamchi kalit har doim indekslanadi. UNIQUE cheklovi ham indeks yaratadi. FOREIGN KEY esa MySQL da avtomatik indeks qo'shadi.

Qaysi ustunlarga indeks kerak? #

UstunIndeks kerakmi
WHERE da tez-tez ishlatiladiganHa
JOIN da bog'lanadigan (FK)Ha, majburiy
ORDER BY da saralanadiganHa
GROUP BY da guruhlanadiganHa
Faqat SELECT da ko'rsatiladiganYo'q
Kam noyob qiymatli (jins, faolmi)Odatda yo'q
Tez-tez o'zgaradiganEhtiyotkorlik bilan
Indeks bepul emas

Har bir indeks:

NarxIzoh
XotiraAlohida tuzilma saqlanadi
INSERT sekinlashadiHar bir indeks yangilanadi
UPDATE sekinlashadiIndekslangan ustun o'zgarsa
DELETE sekinlashadiIndeksdan ham o'chiriladi

10 ta indeksli jadvalda INSERT indekssizdan 3-5 barobar sekin bo'ladi.

Qoida: kerakli indekslarni qo'ying, ortiqchasini o'chiring.

Tarkibiy indekslar #

SQL
CREATE INDEX idx_shahar_baho ON talabalar (shahar, ortacha_baho);

Bu indeks quyidagi so'rovlarda ishlaydi:

SQL
WHERE shahar = 'Toshkent'
WHERE shahar = 'Toshkent' AND ortacha_baho > 4.0
WHERE shahar = 'Toshkent' ORDER BY ortacha_baho

Lekin bularda ishlamaydi:

SQL
WHERE ortacha_baho > 4.0                    -- birinchi ustun yo'q
WHERE ortacha_baho > 4.0 AND shahar = 'X'   -- ishlaydi (tartib muhim emas)
"Chapdan prefiks" qoidasi

(a, b, c) indeksi quyidagi kombinatsiyalarda ishlaydi:

  • a
  • a, b
  • a, b, c

Lekin bularda ishlamaydi:

  • b
  • c
  • b, c

Telefon kitobi bilan solishtiring: u familiya, keyin ism bo'yicha saralangan. Familiya bo'yicha topish oson, faqat ism bo'yicha - imkonsiz.

Ustunlar tartibi juda muhim: eng ko'p filtrlanadigani birinchi bo'lsin.

Indeksni buzadigan so'rovlar #

Bu xatolarni qilmang
SQL
-- 1. Ustunga funksiya qo'llash
WHERE YEAR(yaratilgan) = 2026            -- indeks ISHLAMAYDI
WHERE yaratilgan >= '2026-01-01'
  AND yaratilgan <  '2027-01-01'         -- indeks ISHLAYDI

-- 2. Ustun ustida arifmetika
WHERE narx * 1.12 > 100000               -- ISHLAMAYDI
WHERE narx > 100000 / 1.12               -- ISHLAYDI

-- 3. LIKE boshida %
WHERE ism LIKE '%noza'                   -- ISHLAMAYDI
WHERE ism LIKE 'Dil%'                    -- ISHLAYDI

-- 4. Tur nomuvofiqligi
WHERE telefon_raqami = 998901234567      -- ustun VARCHAR bo'lsa ISHLAMAYDI
WHERE telefon_raqami = '998901234567'    -- ISHLAYDI

-- 5. OR bilan turli ustunlar
WHERE shahar = 'Toshkent' OR email = '[email protected]'   -- ko'pincha ISHLAMAYDI
-- Yechim: UNION bilan bo'lish

Umumiy qoida: indekslangan ustunni chap tomonda toza qoldiring.

EXPLAIN - so'rovni tahlil qilish #

SQL
EXPLAIN SELECT * FROM talabalar WHERE shahar = 'Toshkent';
Natija
+----+-------------+-----------+------+---------------+------------+---------+-------+------+-------+
| id | select_type | table     | type | possible_keys | key        | key_len | ref   | rows | Extra |
+----+-------------+-----------+------+---------------+------------+---------+-------+------+-------+
|  1 | SIMPLE      | talabalar | ref  | idx_shahar    | idx_shahar | 183     | const |    2 |       |
+----+-------------+-----------+------+---------------+------------+---------+-------+------+-------+

Muhim ustunlar #

UstunMa'nosi
typeQanday qidirilmoqda (eng muhim)
keyQaysi indeks ishlatilmoqda
rowsNecha qator o'qiladi (taxminan)
ExtraQo'shimcha amallar

type qiymatlari - yaxshidan yomonga #

QiymatMa'nosiBaho
constBirlamchi kalit bo'yicha, 1 ta qatorAjoyib
eq_refHar bir qator uchun 1 ta mosAjoyib
refIndeks bo'yicha bir nechta qatorYaxshi
rangeIndeks bo'yicha oraliqYaxshi
indexButun indeks o'qiladiO'rtacha
ALLButun jadval o'qiladiYomon
type: ALL ko'rsangiz

Bu to'liq jadval skanerlash degani. Kichik jadvalda muammo emas, lekin katta jadvalda - asosiy sekinlik sababi.

Yechim: WHERE dagi ustunga indeks qo'shing.

Extra ustunidagi ogohlantirishlar #

QiymatMa'nosi
Using indexAjoyib - faqat indeksdan o'qildi
Using whereNormal
Using filesortQo'shimcha saralash - indeks yo'q
Using temporaryVaqtinchalik jadval yaratildi - sekin
SQL
-- Batafsil tahlil (MySQL 8.0+)
EXPLAIN ANALYZE SELECT ... ;

-- JSON formatida
EXPLAIN FORMAT=JSON SELECT ... ;

Qoplovchi indeks (covering index) #

Agar indeks so'rovga kerakli barcha ustunlarni o'z ichiga olsa, baza jadvalga umuman murojaat qilmaydi:

SQL
CREATE INDEX idx_shahar_ism ON talabalar (shahar, ism);

-- Bu so'rov faqat indeksdan o'qiydi - juda tez
SELECT ism FROM talabalar WHERE shahar = 'Toshkent';
Natija
Extra: Using index
Using index - eng yaxshi natija

Bu "jadvalga murojaat qilinmadi, hammasi indeksdan olindi" degani. Bunday so'rovlar odatdagidan bir necha barobar tez ishlaydi.

Aynan shuning uchun SELECT * yomon: u har doim jadvalga murojaat qilishga majbur qiladi.

To'liq matnli qidiruv #

LIKE '%matn%' sekin. Katta matnlar uchun FULLTEXT:

SQL
ALTER TABLE maqolalar ADD FULLTEXT INDEX ft_qidiruv (sarlavha, matn);

SELECT sarlavha,
       MATCH(sarlavha, matn) AGAINST('python algoritm') AS ball
FROM maqolalar
WHERE MATCH(sarlavha, matn) AGAINST('python algoritm')
ORDER BY ball DESC;

-- Mantiqiy rejim
SELECT * FROM maqolalar
WHERE MATCH(sarlavha, matn)
      AGAINST('+python -java' IN BOOLEAN MODE);
BelgiMa'nosi
+sozMajburiy
-sozBo'lmasin
"ibora"Aniq ibora
soz*Prefiks bo'yicha

Sekin so'rovlarni topish #

SQL
-- Sekin so'rovlar jurnalini yoqish
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;          -- 1 soniyadan uzun

-- Hozir bajarilayotgan so'rovlar
SHOW PROCESSLIST;

-- Indekslar hajmi
SELECT
    table_name,
    ROUND(data_length / 1024 / 1024, 1)  AS malumot_mb,
    ROUND(index_length / 1024 / 1024, 1) AS indeks_mb
FROM information_schema.TABLES
WHERE table_schema = 'maktab'
ORDER BY index_length DESC;

Optimizatsiya ro'yxati #

So'rov sekin ishlasa
  1. EXPLAIN bilan boshlang - type: ALL bormi?
  2. WHERE, JOIN, ORDER BY ustunlariga indeks qo'shing
  3. Ustunga funksiya qo'llashni olib tashlang
  4. SELECT * o'rniga kerakli ustunlarni sanang
  5. LIMIT qo'ying
  6. Bog'langan ichki so'rovni JOIN ga aylantiring
  7. LIKE '%...' o'rniga FULLTEXT ishlating
  8. Tarkibiy indeksda ustunlar tartibini tekshiring

Amaliy misol #

SQL
-- Sekin so'rov
EXPLAIN SELECT * FROM buyurtmalar
WHERE YEAR(yaratilgan) = 2026 AND holat = 'yangi'
ORDER BY yaratilgan DESC;
-- type: ALL, rows: 500000, Extra: Using filesort

-- 1-tuzatish: funksiyani olib tashlash
-- 2-tuzatish: tarkibiy indeks
CREATE INDEX idx_holat_sana ON buyurtmalar (holat, yaratilgan);

EXPLAIN SELECT id, mijoz_id, summa, yaratilgan
FROM buyurtmalar
WHERE holat = 'yangi'
  AND yaratilgan >= '2026-01-01'
  AND yaratilgan <  '2027-01-01'
ORDER BY yaratilgan DESC
LIMIT 50;
-- type: range, rows: 1200, Extra: Using where

Natija: 500 000 qator o'rniga 1 200 - 400 barobar kam ish.

Amaliy topshiriq
  1. kutubxona bazasidagi barcha so'rovlaringizga EXPLAIN qo'llang.
  2. type: ALL bo'lganlarini toping.
  3. kitoblar jadvalidagi muallif_id va janr ustunlariga indeks qo'shing.
  4. EXPLAIN ni qayta bajarib, type va rows qanday o'zgarganini yozing.
  5. (janr, yil) tarkibiy indeksini yarating va uch xil so'rovda sinang: faqat janr, faqat yil, ikkalasi birga.
  6. Qoplovchi indeks yarating va Using index chiqishiga erishing.
  7. WHERE YEAR(yil) = 2020 va WHERE yil = 2020 ni solishtiring.
  8. SHOW INDEX FROM kitoblar; bilan barcha indekslarni ko'ring.

Xulosa #

  • Indeks - B-daraxt tuzilmasi; qidiruvni O(n) dan O(log n) ga tushiradi.
  • WHERE, JOIN, ORDER BY, GROUP BY ustunlariga indeks kerak.
  • Indeks bepul emas: INSERT/UPDATE sekinlashadi va xotira sarflanadi.
  • Tarkibiy indeksda "chapdan prefiks" qoidasi amal qiladi - tartib muhim.
  • Ustunga funksiya qo'llash indeksni buzadi.
  • EXPLAIN - asosiy tahlil vositasi; type: ALL yomon, Using index ajoyib.
  • Qoplovchi indeks jadvalga murojaatni butunlay yo'q qiladi.
  • Matn qidiruvi uchun LIKE '%...' emas, FULLTEXT ishlating.

Keyingi bo'limda MySQL ning o'rnatilgan funksiyalarini o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.