Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

Bizga tanish bo'lgan barcha ilovalardagi odatiy stsenariylardan biri ma'lum mezonlar bo'yicha ma'lumotlarni qidirish va uni o'qish oson shaklda ko'rsatishdir. Saralash, guruhlash va sahifalash uchun qo'shimcha imkoniyatlar ham bo'lishi mumkin. Vazifa, nazariy jihatdan, ahamiyatsiz, ammo uni hal qilishda ko'plab ishlab chiquvchilar bir qator xatolarga yo'l qo'yishadi, bu esa keyinchalik mahsuldorlikka olib keladi. Keling, ushbu muammoni hal qilishning turli xil variantlarini ko'rib chiqishga harakat qilaylik va eng samarali amalga oshirishni tanlash bo'yicha tavsiyalarni ishlab chiqaylik.

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

№1 sahifalash opsiyasi

Aqlga keladigan eng oddiy variant - qidiruv natijalarini eng klassik shaklda sahifama-sahifa ko'rsatish.

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar
Aytaylik, sizning ilovangiz relyatsion ma'lumotlar bazasidan foydalanadi. Bunday holda, ushbu shakldagi ma'lumotlarni ko'rsatish uchun siz ikkita SQL so'rovini bajarishingiz kerak bo'ladi:

  • Joriy sahifa uchun qatorlarni oling.
  • Qidiruv mezonlariga mos keladigan satrlarning umumiy sonini hisoblang - bu sahifalarni ko'rsatish uchun kerak.

Misol tariqasida test MS SQL ma'lumotlar bazasidan foydalangan holda birinchi so'rovni ko'rib chiqamiz AdventureWorks 2016 server uchun. Buning uchun Sales.SalesOrderHeader jadvalidan foydalanamiz:

SELECT * FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
OFFSET 0 ROWS
FETCH NEXT 50 ROWS ONLY

Yuqoridagi so'rov ro'yxatdagi dastlabki 50 ta buyurtmani, qo'shilish sanasi bo'yicha tartiblangan holda, boshqacha qilib aytganda, eng so'nggi 50 ta buyurtmani qaytaradi.

U test bazasida tez ishlaydi, lekin keling, bajarilish rejasi va kiritish-chiqarish statistikasini ko'rib chiqamiz:

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

Table 'SalesOrderHeader'. Scan count 1, logical reads 698, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Har bir soʻrov uchun kiritish/chiqarish statistikasini soʻrovning bajarilish vaqtida SET STATISTICS IO ON buyrugʻini ishga tushirish orqali olishingiz mumkin.

Ijro rejasidan ko'rinib turibdiki, eng ko'p resurs talab qiladigan variant manba jadvalining barcha qatorlarini qo'shilgan sana bo'yicha tartiblashdir. Va muammo shundaki, jadvalda qancha ko'p qatorlar paydo bo'lsa, saralash "qiyinroq" bo'ladi. Amalda, bunday holatlardan qochish kerak, shuning uchun qo'shilgan sanaga indeks qo'shamiz va resurslar iste'moli o'zgarganligini bilib olaylik:

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

Table 'SalesOrderHeader'. Scan count 1, logical reads 165, physical reads 0, read-ahead reads 5, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Bu ancha yaxshilangani aniq. Ammo barcha muammolar hal qilindimi? Tovarlarning umumiy qiymati 100 AQSh dollaridan oshadigan buyurtmalarni qidirish uchun so'rovni o'zgartiramiz:

SELECT * FROM Sales.SalesOrderHeader
WHERE SubTotal > 100
ORDER BY OrderDate DESC
OFFSET 0 ROWS
FETCH NEXT 50 ROWS ONLY

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

Table 'SalesOrderHeader'. Scan count 1, logical reads 1081, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Bizda kulgili vaziyat bor: so'rovlar rejasi avvalgisidan ko'ra yomonroq emas, lekin mantiqiy o'qishlarning haqiqiy soni to'liq jadvalni skanerlash bilan solishtirganda deyarli ikki baravar ko'p. Chiqish yo'li bor - agar biz allaqachon mavjud indeksdan kompozit indeks tuzsak va tovarlarning umumiy narxini ikkinchi maydon sifatida qo'shsak, biz yana 165 mantiqiy o'qishni olamiz:

CREATE INDEX IX_SalesOrderHeader_OrderDate_SubTotal on Sales.SalesOrderHeader(OrderDate, SubTotal);

Ushbu misollar seriyasini uzoq vaqt davom ettirish mumkin, ammo men bu erda aytmoqchi bo'lgan ikkita asosiy fikr:

  • Qidiruv so'roviga har qanday yangi mezon yoki tartiblash tartibini qo'shish qidiruv so'rovi tezligiga sezilarli ta'sir ko'rsatishi mumkin.
  • Ammo qidiruv so'zlariga mos keladigan barcha natijalarni emas, balki ma'lumotlarning faqat bir qismini olib tashlashimiz kerak bo'lsa, bunday so'rovni optimallashtirishning ko'plab usullari mavjud.

Endi boshida aytib o'tilgan ikkinchi so'rovga - qidiruv mezoniga javob beradigan yozuvlar sonini hisoblaydigan so'rovga o'tamiz. Xuddi shu misolni olaylik - 100 dollardan ortiq buyurtmalarni qidirish:

SELECT COUNT(1) FROM Sales.SalesOrderHeader
WHERE SubTotal > 100

Yuqorida ko'rsatilgan kompozit indeksni hisobga olgan holda biz quyidagilarni olamiz:

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

Table 'SalesOrderHeader'. Scan count 1, logical reads 698, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

So'rovning butun indeks bo'ylab o'tishi ajablanarli emas, chunki SubTotal maydoni birinchi holatda emas, shuning uchun so'rov uni ishlata olmaydi. Muammo SubTotal maydoniga boshqa indeks qo'shish orqali hal qilinadi va natijada u faqat 48 mantiqiy o'qishni beradi.

Miqdorlarni hisoblash bo'yicha so'rovlarga yana bir nechta misol keltirishingiz mumkin, ammo mohiyati bir xil bo'lib qoladi: ma'lumotlarning bir qismini qabul qilish va umumiy miqdorni hisoblash ikki xil so'rovdir, va har biri optimallashtirish uchun o'z choralarini talab qiladi. Umuman olganda, siz ikkala so'rov uchun bir xil darajada yaxshi ishlaydigan indekslar kombinatsiyasini topa olmaysiz.

Shunga ko'ra, bunday qidiruv echimini ishlab chiqishda aniqlanishi kerak bo'lgan muhim talablardan biri bu biznes uchun topilgan ob'ektlarning umumiy sonini ko'rish haqiqatan ham muhimmi yoki yo'qmi. Ko'pincha shunday bo'ladiki, yo'q. Va ma'lum sahifa raqamlari bo'yicha navigatsiya, menimcha, juda tor doiradagi yechim, chunki ko'pchilik peyjing stsenariylari "keyingi sahifaga o'tish" kabi ko'rinadi.

№2 sahifalash opsiyasi

Faraz qilaylik, foydalanuvchilar topilgan ob'ektlarning umumiy sonini bilish qiziqtirmaydi. Keling, qidiruv sahifasini soddalashtirishga harakat qilaylik:

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar
Aslida, o'zgargan yagona narsa shundaki, aniq sahifa raqamlariga o'tishning hech qanday usuli yo'q va endi bu jadvalni ko'rsatish uchun qancha bo'lishi mumkinligini bilish shart emas. Ammo savol tug'iladi - jadval keyingi sahifa uchun ma'lumotlar mavjudligini qanday biladi ("Keyingi" havolasini to'g'ri ko'rsatish uchun)?

Javob juda oddiy: siz ma'lumotlar bazasidan ko'rsatish uchun kerak bo'lganidan ko'proq yozuvni o'qishingiz mumkin va ushbu "qo'shimcha" yozuvning mavjudligi keyingi qism mavjudligini ko'rsatadi. Shunday qilib, ma'lumotlarning bir sahifasini olish uchun faqat bitta so'rovni bajarishingiz kerak, bu esa ish faoliyatini sezilarli darajada yaxshilaydi va bunday funksiyani qo'llab-quvvatlashni osonlashtiradi. Mening amaliyotimda, yozuvlarning umumiy sonini sanashdan bosh tortgan holda, natijalarni 4-5 barobarga tezlashtirdi.

Ushbu yondashuv uchun bir nechta foydalanuvchi interfeysi variantlari mavjud: "orqaga" va "oldinga" buyruqlari, yuqoridagi misolda bo'lgani kabi, ko'rsatilgan natijalarga shunchaki yangi qism qo'shadigan "ko'proq yuklash" tugmasi, "cheksiz aylantirish" ishlaydi. "ko'proq yuklash" tamoyili bo'yicha, lekin keyingi qismni olish uchun signal foydalanuvchi barcha ko'rsatilgan natijalarni oxirigacha aylantirishi kerak. Vizual yechim qanday bo'lishidan qat'iy nazar, ma'lumotlarni tanlash printsipi bir xil bo'lib qoladi.

Peyjingni amalga oshirishning nuanslari

Yuqorida keltirilgan barcha so'rov misollarida "ofset + count" usuli qo'llaniladi, bunda so'rovning o'zi natija qatorlarini qaysi tartibda va qancha qatorni qaytarish kerakligini ko'rsatadi. Birinchidan, keling, bu holda parametrlarni o'tkazishni qanday tashkil qilish kerakligini ko'rib chiqaylik. Amalda men bir nechta usullarni uchratdim:

  • So'ralgan sahifaning seriya raqami (pageIndex), sahifa o'lchami (pageSize).
  • Qaytariladigan birinchi yozuvning seriya raqami (startIndex), natijadagi yozuvlarning maksimal soni (hisoblash).
  • Qaytariladigan birinchi yozuvning tartib raqami (startIndex), qaytariladigan oxirgi yozuvning tartib raqami (endIndex).

Bir qarashda, bu juda oddiy bo'lib tuyulishi mumkinki, hech qanday farq yo'q. Lekin bu shunday emas - eng qulay va universal variant ikkinchi (startIndex, count). Buning bir qancha sabablari bor:

  • Yuqorida keltirilgan +1 yozuvni tekshirish usuli uchun pageIndex va pageSize bilan birinchi variant juda noqulay. Misol uchun, biz har bir sahifada 50 ta xabarni ko'rsatishni xohlaymiz. Yuqoridagi algoritmga ko'ra, kerak bo'lgandan ko'ra yana bitta yozuvni o'qishingiz kerak. Agar bu "+1" serverda o'rnatilmagan bo'lsa, birinchi sahifada biz 1 dan 51 gacha, ikkinchisi uchun - 51 dan 101 gacha va hokazolarni so'rashimiz kerak. Agar siz sahifa o'lchamini 51 ga belgilasangiz va pageIndex ni oshirsangiz, ikkinchi sahifa 52 dan 102 gacha qaytadi va hokazo. Shunga ko'ra, birinchi variantda, keyingi sahifaga o'tish uchun tugmani to'g'ri amalga oshirishning yagona yo'li, serverning "qo'shimcha" qatorni tekshirishi kerak, bu juda noaniq nuance bo'ladi.
  • Uchinchi variant umuman mantiqiy emas, chunki ko'pgina ma'lumotlar bazalarida so'rovlarni bajarish uchun siz hali ham oxirgi yozuvning indeksini emas, balki hisobni topshirishingiz kerak bo'ladi. endIndex-dan startIndex-ni ayirish oddiy arifmetik operatsiya bo'lishi mumkin, ammo bu erda ortiqcha.

Endi biz "ofset + miqdor" orqali peyjingni amalga oshirishning kamchiliklarini tasvirlashimiz kerak:

  • Har bir keyingi sahifani olish avvalgisiga qaraganda qimmatroq va sekinroq bo'ladi, chunki ma'lumotlar bazasi hali ham qidirish va saralash mezonlariga ko'ra "boshidan" barcha yozuvlarni ko'rib chiqishi va keyin kerakli bo'lakda to'xtashi kerak bo'ladi.
  • Hamma ma'lumotlar bazasi ma'lumotlar bazasi ushbu yondashuvni qo'llab-quvvatlamaydi.

Muqobil variantlar mavjud, ammo ular ham nomukammal. Ushbu yondashuvlarning birinchisi "tugmachalar to'plamini paging" yoki "izlash usuli" deb nomlanadi va quyidagilardan iborat: qismni olgandan so'ng, siz sahifadagi oxirgi yozuvdagi maydon qiymatlarini eslab qolishingiz va keyin ularni olish uchun ishlatishingiz mumkin. keyingi qism. Misol uchun, biz quyidagi so'rovni bajardik:

SELECT * FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC
OFFSET 0 ROWS
FETCH NEXT 50 ROWS ONLY

Va oxirgi yozuvda biz buyurtma sanasi qiymatini oldik "2014-06-29". Keyin keyingi sahifani olish uchun buni qilishga urinib ko'rishingiz mumkin:

SELECT * FROM Sales.SalesOrderHeader
WHERE OrderDate < '2014-06-29'
ORDER BY OrderDate DESC
OFFSET 0 ROWS
FETCH NEXT 50 ROWS ONLY

Muammo shundaki, OrderDate noyob bo'lmagan maydon va yuqorida ko'rsatilgan shart juda ko'p talab qilinadigan qatorlarni o'tkazib yuborishi mumkin. Ushbu so'rovga noaniqlik kiritish uchun shartga noyob maydon qo'shishingiz kerak (75074 birinchi qismdagi asosiy kalitning oxirgi qiymati deb hisoblang):

SELECT * FROM Sales.SalesOrderHeader
WHERE (OrderDate = '2014-06-29' AND SalesOrderID < 75074)
   OR (OrderDate < '2014-06-29')
ORDER BY OrderDate DESC, SalesOrderID DESC
OFFSET 0 ROWS
FETCH NEXT 50 ROWS ONLY

Ushbu parametr to'g'ri ishlaydi, lekin umuman optimallashtirish qiyin bo'ladi, chunki shartda OR operatori mavjud. Agar asosiy kalitning qiymati Buyurtma sanasi oshgani sayin oshsa, SalesOrderID bo'yicha faqat filtr qoldirish orqali shartni soddalashtirish mumkin. Ammo, agar asosiy kalitning qiymatlari va natija saralanadigan maydon o'rtasida qat'iy bog'liqlik bo'lmasa, ko'pgina DBMSlarda bu OR dan qochib bo'lmaydi. Men biladigan istisnolardan biri bu PostgreSQL boʻlib, u kortejli taqqoslashni toʻliq qoʻllab-quvvatlaydi va yuqoridagi shartni “WHERE (OrderDate, SalesOrderID) < ('2014-06-29', 75074)” deb yozish mumkin. Ushbu ikkita maydonga ega kompozit kalitni hisobga olsak, bunday so'rov juda oson bo'lishi kerak.

Ikkinchi muqobil yondashuvni, masalan, ichida topish mumkin ElasticSearch aylantirish API yoki Kosmos DB — so'rov ma'lumotlarga qo'shimcha ravishda ma'lumotlarning keyingi qismini olishingiz mumkin bo'lgan maxsus identifikatorni qaytarganda. Agar ushbu identifikatorning ishlash muddati cheksiz bo'lsa (Comsos DB da bo'lgani kabi), bu sahifalar o'rtasida ketma-ket o'tish bilan peyjingni amalga oshirishning ajoyib usuli (yuqorida aytib o'tilgan №2 variant). Uning mumkin bo'lgan kamchiliklari: u barcha DBMSlarda qo'llab-quvvatlanmaydi; natijada paydo bo'lgan keyingi bo'lak identifikatori cheklangan umrga ega bo'lishi mumkin, bu odatda foydalanuvchi o'zaro ta'sirini amalga oshirish uchun mos kelmaydi (masalan, ElasticSearch scroll API).

Kompleks filtrlash

Keling, vazifani yanada murakkablashtiraylik. Aytaylik, onlayn-do'konlardan hamma uchun tanish bo'lgan qirrali qidiruvni amalga oshirish talabi mavjud. Buyurtmalar jadvaliga asoslangan yuqoridagi misollar bu holatda unchalik aniq emas, shuning uchun AdventureWorks ma'lumotlar bazasidan Mahsulotlar jadvaliga o'tamiz:

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar
Faceli qidiruv ortida qanday g'oya bor? Haqiqat shundaki, har bir filtr elementi uchun ushbu mezonga javob beradigan yozuvlar soni ko'rsatilgan boshqa barcha toifalarda tanlangan filtrlarni hisobga olgan holda.

Misol uchun, agar biz ushbu misolda Velosipedlar toifasini va Qora rangni tanlasak, jadval faqat qora velosipedlarni ko'rsatadi, lekin:

  • Kategoriyalar guruhidagi har bir mezon uchun ushbu toifadagi mahsulotlar soni qora rangda ko'rsatiladi.
  • "Ranglar" guruhining har bir mezoni uchun ushbu rangdagi velosipedlar soni ko'rsatiladi.

Mana shunday sharoitlar uchun natija chiqishiga misol:

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar
Agar siz "Kiyim" toifasini ham tekshirsangiz, jadvalda stokda bo'lgan qora kiyimlar ham ko'rsatiladi. "Rang" bo'limidagi qora mahsulotlar soni ham yangi shartlarga muvofiq qayta hisoblab chiqiladi, faqat "Kategoriyalar" bo'limida hech narsa o'zgarmaydi ... Umid qilamanki, bu misollar odatiy qirrali qidiruv algoritmini tushunish uchun etarli.

Keling, buni relyatsion asosda qanday amalga oshirish mumkinligini tasavvur qilaylik. Kategoriya va Rang kabi mezonlarning har bir guruhi alohida so'rovni talab qiladi:

SELECT pc.ProductCategoryID, pc.Name, COUNT(1) FROM Production.Product p
  INNER JOIN Production.ProductSubcategory ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID
  INNER JOIN Production.ProductCategory pc ON ps.ProductCategoryID = pc.ProductCategoryID
WHERE p.Color = 'Black'
GROUP BY pc.ProductCategoryID, pc.Name
ORDER BY COUNT(1) DESC

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar

SELECT Color, COUNT(1) FROM Production.Product p
  INNER JOIN Production.ProductSubcategory ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID
WHERE ps.ProductCategoryID = 1 --Bikes
GROUP BY Color
ORDER BY COUNT(1) DESC

Qidiruv natijalari chiqishi va ishlash bilan bog'liq muammolar
Bu yechimning nimasi yomon? Bu juda oddiy - u yaxshi miqyosda emas. Har bir filtr bo'limi miqdorlarni hisoblash uchun alohida so'rovni talab qiladi va bu so'rovlar eng oson emas. Onlayn do'konlarda ba'zi toifalarda bir necha o'nlab filtr bo'limlari bo'lishi mumkin, bu jiddiy ishlash muammosi bo'lishi mumkin.

Odatda bu bayonotlardan keyin menga ba'zi echimlar taklif etiladi, xususan:

  • Barcha miqdorlarni bitta so'rovga birlashtiring. Texnik jihatdan bu UNION kalit so'zidan foydalanish mumkin, lekin bu unchalik ko'p yordam bermaydi - ma'lumotlar bazasi hali ham har bir fragmentni noldan bajarishi kerak.
  • Kesh miqdori. Bu menga deyarli har doim muammoni tasvirlaganimda taklif qilinadi. Ogohlantirish shundaki, bu umuman mumkin emas. Aytaylik, bizda 10 ta "faset" bor, ularning har biri 5 ta qiymatga ega. Xuddi shu onlayn-do'konlarda ko'rish mumkin bo'lgan narsalar bilan solishtirganda, bu juda "kamtarona" holat. Bir faset elementini tanlash boshqa 9 ta miqdorga ta'sir qiladi, boshqacha aytganda, har bir mezon kombinatsiyasi uchun miqdorlar boshqacha bo'lishi mumkin. Bizning misolimizda foydalanuvchi tanlashi mumkin bo'lgan jami 50 ta mezonlar mavjud, shuning uchun 250 ta mumkin bo'lgan kombinatsiyalar mavjud. Bunday ma'lumotlar qatorini to'ldirish uchun xotira yoki vaqt etarli emas. Bu erda siz e'tiroz bildirishingiz va barcha kombinatsiyalar haqiqiy emasligini aytishingiz mumkin va foydalanuvchi kamdan-kam hollarda 5-10 dan ortiq mezonni tanlaydi. Ha, dangasa yuklash va faqat tanlangan miqdorni keshlash mumkin, ammo tanlovlar qancha ko'p bo'lsa, bunday kesh samaradorligi shunchalik kam bo'ladi va javob berish vaqtidagi muammolar shunchalik sezilarli bo'ladi (ayniqsa, agar ma'lumotlar to'plami muntazam ravishda o'zgaradi).

Yaxshiyamki, bunday muammo uzoq vaqtdan beri katta hajmdagi ma'lumotlarda oldindan taxmin qilinadigan samarali echimlarga ega. Ushbu variantlardan har biri uchun tomonlarni qayta hisoblash va natijalar sahifasini serverga ikkita parallel qo'ng'iroqlarga bo'lish va foydalanuvchi interfeysini fasetlar bo'yicha ma'lumotlarni yuklash "to'sqinlik qilmasligi" uchun tashkil qilish mantiqan. Qidiruv natijalari.

  • Iloji boricha kamdan-kam hollarda "jabhalar" ni to'liq qayta hisoblashni chaqiring. Misol uchun, har safar qidiruv mezonlari o'zgarganda hamma narsani qayta hisoblab chiqmang, aksincha, joriy shartlarga mos keladigan natijalarning umumiy sonini toping va foydalanuvchidan ularni ko'rsatishni taklif qiling - "1425 ta yozuv topildi, ko'rsatingmi?" Foydalanuvchi qidiruv so'zlarini o'zgartirishni davom ettirishi yoki "ko'rsatish" tugmasini bosishi mumkin. Faqat ikkinchi holatda, natijalarni olish va barcha "jabhalar" bo'yicha miqdorlarni qayta hisoblash bo'yicha barcha so'rovlar bajariladi. Bunday holda, siz osongina ko'rib turganingizdek, natijalarning umumiy sonini va uni optimallashtirishni olish uchun so'rov bilan shug'ullanishingiz kerak bo'ladi. Ushbu usulni ko'plab kichik onlayn-do'konlarda topish mumkin. Shubhasiz, bu muammo uchun panacea emas, lekin oddiy holatlarda bu yaxshi murosaga kelishi mumkin.
  • Solr, ElasticSearch, Sphinx va boshqalar kabi natijalarni topish va tomonlarni hisoblash uchun qidiruv tizimlaridan foydalaning. Ularning barchasi "yuzlarni" qurish uchun mo'ljallangan va teskari indeks tufayli buni juda samarali bajaradi. Qidiruv mexanizmlari qanday ishlaydi, nima uchun bunday hollarda ular umumiy maqsadli ma'lumotlar bazalariga qaraganda samaraliroq, qanday amaliyotlar va tuzoqlar mavjud - bu alohida maqola uchun mavzu. Bu erda men sizning e'tiboringizni qidiruv tizimi asosiy ma'lumotlarni saqlash o'rnini bosa olmasligiga qaratmoqchiman, u qo'shimcha sifatida ishlatiladi: qidiruv uchun tegishli bo'lgan asosiy ma'lumotlar bazasidagi har qanday o'zgarishlar qidiruv indeksiga sinxronlashtiriladi; Qidiruv tizimi odatda faqat qidiruv tizimi bilan o'zaro ishlaydi va asosiy ma'lumotlar bazasiga kirmaydi. Bu erda eng muhim nuqtalardan biri bu sinxronizatsiyani ishonchli tarzda qanday tashkil qilishdir. Bularning barchasi "reaktsiya vaqti" talablariga bog'liq. Agar asosiy ma'lumotlar bazasidagi o'zgarish va uning qidiruvdagi "namoyishi" o'rtasidagi vaqt muhim bo'lmasa, siz yaqinda o'zgartirilgan yozuvlarni har bir necha daqiqada qidiradigan va ularni indekslaydigan xizmatni yaratishingiz mumkin. Eng qisqa javob vaqtini istasangiz, shunga o'xshash narsani amalga oshirishingiz mumkin tranzaksiya chiqish qutisi qidiruv xizmatiga yangilanishlarni yuborish uchun.

topilmalar

  1. Server tomonidagi pagingni amalga oshirish muhim murakkablikdir va faqat tez o'sib borayotgan yoki oddiygina katta ma'lumotlar to'plamlari uchun mantiqiy. "Katta" yoki "tez o'sayotgan" ni qanday baholashning mutlaqo aniq retsepti yo'q, lekin men ushbu yondashuvga amal qilaman:
    • Agar server vaqti va tarmoq uzatilishini hisobga olgan holda ma'lumotlarning to'liq to'plamini olish odatda ishlash talablariga javob bersa, server tomonida peyjingni amalga oshirishning ma'nosi yo'q.
    • Yaqin kelajakda ishlash bilan bog'liq muammolar kutilmaydigan vaziyat bo'lishi mumkin, chunki ma'lumotlar kam, lekin ma'lumotlar yig'ish doimiy ravishda o'sib bormoqda. Agar kelajakda ba'zi ma'lumotlar to'plami avvalgi fikrni qondirmasa, darhol peyjingni boshlash yaxshiroqdir.
  2. Agar biznes tomonidan natijalarning umumiy sonini ko'rsatish yoki sahifa raqamlarini ko'rsatish bo'yicha qat'iy talab bo'lmasa va tizimingizda qidiruv tizimi bo'lmasa, ushbu fikrlarni amalga oshirmaslik va №2 variantni ko'rib chiqish yaxshiroqdir.
  3. Agar qirrali qidiruv uchun aniq talab mavjud bo'lsa, unumdorlikni yo'qotmasdan ikkita variant mavjud:
    • Qidiruv mezonlari har safar o'zgarganda barcha miqdorlarni qayta hisoblamang.
    • Solr, ElasticSearch, Sphinx va boshqalar kabi qidiruv tizimlaridan foydalaning. Ammo shuni tushunish kerakki, u asosiy ma'lumotlar bazasini almashtira olmaydi va qidiruv muammolarini hal qilish uchun asosiy xotiraga qo'shimcha sifatida ishlatilishi kerak.
  4. Bundan tashqari, fasetli qidiruvda qidiruv natijalari sahifasini qidirish va hisoblashni ikkita parallel so'rovga bo'lish mantiqan to'g'ri keladi. Miqdorlarni hisoblash natijalarni olishdan ko'ra ko'proq vaqt talab qilishi mumkin, ammo natijalar foydalanuvchi uchun muhimroqdir.
  5. Agar siz qidirish uchun SQL ma'lumotlar bazasidan foydalanayotgan bo'lsangiz, ushbu qism bilan bog'liq har qanday kod o'zgarishi tegishli ma'lumotlar hajmida (jonli ma'lumotlar bazasidagi hajmdan oshib ketish) ishlash uchun yaxshi sinovdan o'tkazilishi kerak. Shuningdek, ma'lumotlar bazasining barcha nusxalarida va ayniqsa "jonli" da so'rovlarni bajarish vaqtini monitoring qilish tavsiya etiladi. Rivojlanish bosqichida so'rov rejalari bilan hamma narsa yaxshi bo'lsa ham, ma'lumotlar hajmi oshgani sayin, vaziyat sezilarli darajada o'zgarishi mumkin.

Manba: www.habr.com

a Izoh qo'shish