Sayt ishga tushgan paytda bazada bir necha yuz qator bo'ladi va har qanday so'rov bir zumda bajariladi. Bir-ikki yildan keyin esa buyurtmalar, mahsulotlar va mijozlar jadvallarida yuz minglab qator to'planadi, ilgari sezilmagan so'rovlar esa soniyalab davom eta boshlaydi. Ko'pincha buning sababi server kuchsizligida emas, balki kerakli indeks yo'qligida bo'ladi. To'g'ri qo'yilgan bitta indeks og'ir so'rovni bir necha barobar, ba'zan yuzlab barobar tezlashtirishi mumkin.
Indeks nima va u qanday ishlaydi
Indeksni kitob oxiridagi alifbo ko'rsatkichiga o'xshatish mumkin. Kerakli mavzuni topish uchun butun kitobni varaqlab chiqmaysiz, ko'rsatkichdan sahifa raqamini topib, to'g'ridan-to'g'ri o'sha joyni ochasiz. MySQL ham indekssiz ustun bo'yicha qidirganda jadvaldagi har bir qatorni birma-bir tekshiradi, bunga to'liq jadval skaneri deyiladi. Indeks esa ustun qiymatlarini tartiblangan daraxt ko'rinishida saqlaydi va server kerakli qatorlarga bir necha qadamda yetib boradi.
InnoDB jadvallarida asosiy kalit avtomatik ravishda indeks hisoblanadi, shuning uchun id bo'yicha qidiruv doim tez. Muammo boshqa ustunlar bo'yicha qidirilganda boshlanadi: telefon raqami, holat, kategoriya, sana. Aynan shu ustunlarga qo'shimcha indekslar kerak bo'ladi.
Qaysi ustunlarga indeks kerak
Indeks qo'shish uchun eng yaxshi nomzodlar so'rovlarda tez-tez ishlatiladigan ustunlardir. Ular odatda WHERE shartida filtrlash uchun, JOIN orqali jadvallarni bog'lash uchun va ORDER BY bilan saralash uchun ishlatiladi. Qaysi so'rovlar sekin ekanini taxmin qilmasdan, sekin so'rovlar logi yoki ilovaning so'rov tahlili vositalari orqali aniqlab olish to'g'ri yo'l.
Shu bilan birga, har bir ustunga indeks qo'yish ham to'g'ri emas. Faqat ikki-uch xil qiymat qabul qiladigan ustun, masalan "faol" yoki "nofaol" holati, o'zi alohida indeks sifatida kam foyda beradi, chunki u qatorlarning yarmini qaytaradi. Bunday ustun ko'proq tarkibiy indeksning bir qismi sifatida foydali bo'ladi.
Muammoni EXPLAIN bilan ko'rish
Indeks qo'shishdan oldin so'rovning hozirgi bajarilish rejasini ko'rib chiqing. Quyidagi misolda yetkazib berish xizmatining buyurtmalar jadvalidan mijoz telefoni bo'yicha qidirilmoqda:
EXPLAIN SELECT id, status, total
FROM orders
WHERE phone = '998901234567'
ORDER BY created_at DESC;
Natijada type ustunida ALL, key ustunida NULL va rows ustunida jadvaldagi qatorlar soniga yaqin raqam ko'rinsa, server butun jadvalni ko'rib chiqayotgan bo'ladi. Extra ustunidagi Using filesort esa natijalar qo'shimcha ravishda alohida saralanayotganini bildiradi.
Indeksni qo'shish
Indeks ALTER TABLE yoki CREATE INDEX buyrug'i bilan qo'shiladi. Filtrlash va saralash birga ishlatilganda tarkibiy indeks eng yaxshi natija beradi: avval tenglik sharti bo'lgan ustun, keyin saralash ustuni yoziladi. Mavjud indekslarni ko'rish uchun SHOW INDEX ishlatiladi:
SHOW INDEX FROM orders;
ALTER TABLE orders
ADD INDEX idx_phone_created (phone, created_at),
ALGORITHM=INPLACE, LOCK=NONE;
Zamonaviy MySQL versiyalarida InnoDB jadvaliga ikkilamchi indeks qo'shish odatda jadvalni o'qish va yozish uchun bloklamasdan bajariladi. ALGORITHM=INPLACE, LOCK=NONE qismi buni aniq talab qiladi: agar shunday bajarib bo'lmasa, MySQL jadvalni qulflash o'rniga xato qaytaradi. Shunga qaramay, juda katta jadvalda indeks qurish vaqt va qo'shimcha disk joyini talab qiladi, shuning uchun bu ishni tashrifchilar kam bo'lgan vaqtda va oldindan zaxira nusxa olib bajarish xavfsizroq.
Tarkibiy indeksda tartib muhim
Bir nechta ustundan iborat indeks chap tomondan boshlab ishlatiladi. (phone, created_at) indeksi faqat phone bo'yicha qidiruvga ham, phone va created_at bo'yicha birgalikdagi so'rovga ham yordam beradi. Lekin faqat created_at bo'yicha qidirilganda bu indeks odatda ishlatilmaydi, chunki birinchi ustun shartda qatnashmaydi. Shuning uchun ustunlar tartibini real so'rovlarga qarab tanlash kerak.
Indeksni ishlatib bo'lmaydigan holatlar
Ba'zan indeks bor, lekin so'rov baribir sekin. Buning bir nechta odatiy sabablari bor va ularni bilish ko'p vaqtni tejaydi:
- Ustunga funksiya qo'llanganda, masalan
WHERE YEAR(created_at) = 2026, indeks ishlamaydi. Uni oraliq ko'rinishida yozish kerak:created_at >= '2026-01-01' AND created_at < '2027-01-01'. LIKE '%matn%'kabi boshida foiz belgisi bo'lgan qidiruv oddiy indeksdan foydalana olmaydi,LIKE 'matn%'esa foydalanadi.- Ustun turi bilan qiymat turi mos kelmasa, masalan matnli ustunni raqam bilan solishtirsangiz, MySQL har qatorni o'zgartirib tekshirishga majbur bo'lishi mumkin.
Indeksning narxi
Indeks bepul emas. Har bir qo'shimcha indeks diskda joy egallaydi va jadvalga yangi qator qo'shilganda yoki o'zgartirilganda indeks ham yangilanishi kerak, shuning uchun yozish amallari biroz sekinlashadi. Ko'p o'qiladigan saytlarda bu narx odatda arzimas, lekin juda ko'p yoziladigan log jadvallarida ortiqcha indekslar yuk bo'lishi mumkin. Ishlatilmayotgan va bir-birini takrorlaydigan indekslarni vaqti-vaqti bilan ko'rib chiqib, olib tashlash foydali.
Amaliy misol: yetkazib berish xizmati operatorlari
Andijondagi yetkazib berish xizmatining misol.uz sayti ichida operatorlar uchun boshqaruv paneli bor edi. Mijoz qo'ng'iroq qilganda operator telefon raqami bo'yicha uning buyurtmalarini qidirardi va har qidiruv to'rt-besh soniya davom etardi. Buyurtmalar jadvalida bir yarim million qator bor edi, phone ustunida esa indeks yo'q edi. Yuqoridagi tarkibiy indeks qo'shilgach, EXPLAIN natijasida ko'rib chiqiladigan qatorlar soni millionlardan bir necha o'ntaga tushdi va qidiruv bir zumda natija bera boshladi.
Bu ishga server sozlamalarini o'zgartirish yoki kuchliroq tarifga o'tish kerak bo'lmadi. Shared hostingda ham indeksni phpMyAdmin orqali o'z bazangizda qo'shishingiz mumkin, chunki bu foydalanuvchi huquqlari doirasidagi amal. sayt.uz hostingida qaysi so'rov sekin ekanini aniqlashda qiynalsangiz, kabinet orqali texnik yordamga murojaat qilish mumkin.