Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

Бидний мэддэг бүх програмын ердийн хувилбаруудын нэг бол тодорхой шалгуурын дагуу өгөгдлийг хайж олох, уншихад хялбар хэлбэрээр харуулах явдал юм. Мөн эрэмбэлэх, бүлэглэх, пейжинг хийх нэмэлт сонголтууд байж болно. Даалгавар нь онолын хувьд өчүүхэн боловч үүнийг шийдэхдээ олон хөгжүүлэгчид хэд хэдэн алдаа гаргадаг бөгөөд энэ нь хожим бүтээмжийг бууруулдаг. Энэ асуудлыг шийдэх янз бүрийн хувилбаруудыг авч үзэх, хамгийн үр дүнтэй хэрэгжилтийг сонгох зөвлөмжийг боловсруулахыг хичээцгээе.

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

1-р хуудасны сонголт

Хамгийн энгийн сонголт бол хайлтын үр дүнг хамгийн сонгодог хэлбэрээр нь хуудас бүрээр харуулах явдал юм.

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд
Таны програм харилцааны мэдээллийн санг ашигладаг гэж бодъё. Энэ тохиолдолд мэдээллийг энэ хэлбэрээр харуулахын тулд та хоёр SQL асуулга ажиллуулах шаардлагатай болно.

  • Одоогийн хуудасны мөрүүдийг авах.
  • Хайлтын шалгуурт тохирсон мөрийн нийт тоог тооцоолох - энэ нь хуудсыг харуулахад шаардлагатай.

Жишээ болгон тестийн MS SQL мэдээллийн санг ашиглан эхний хайлтыг авч үзье AdventureWorks 2016 серверийн хувьд. Энэ зорилгоор бид Sales.SalesOrderHeader хүснэгтийг ашиглана:

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

Дээрх асуулга нь жагсаалтын эхний 50 захиалгыг нэмэх огноогоор эрэмбэлсэн, өөрөөр хэлбэл хамгийн сүүлийн 50 захиалгыг буцаана.

Энэ нь туршилтын суурь дээр хурдан ажилладаг, гэхдээ гүйцэтгэлийн төлөвлөгөө болон оролт гаралтын статистикийг харцгаая:

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

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.

Та асуулга ажиллах хугацаанд SET STATISTICS IO ON командыг ажиллуулснаар асуулга бүрийн оролт гаралтын статистик мэдээллийг авах боломжтой.

Гүйцэтгэлийн төлөвлөгөөнөөс харахад хамгийн их нөөц шаардсан сонголт бол эх хүснэгтийн бүх мөрийг нэмсэн огноогоор нь эрэмбэлэх явдал юм. Асуудал нь хүснэгтэд олон мөр гарч ирэх тусам эрэмбэлэх нь "хэцүү" байх болно. Практикт ийм нөхцөл байдлаас зайлсхийх хэрэгтэй тул нэмсэн огноонд индекс нэмж, нөөцийн хэрэглээ өөрчлөгдсөн эсэхийг харцгаая.

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

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.

Энэ нь хамаагүй дээрдсэн нь ойлгомжтой. Гэхдээ бүх асуудал шийдэгдсэн үү? Барааны нийт өртөг 100 доллараас давсан захиалгыг хайхын тулд асуулгыг өөрчилье:

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

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

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.

Бидэнд инээдтэй нөхцөл байдал бий: асуулгын төлөвлөгөө нь өмнөхөөсөө муу биш боловч логик уншлагын бодит тоо нь хүснэгтийг бүрэн сканнердсантай харьцуулахад бараг хоёр дахин их байна. Гарах арга бий - хэрэв бид аль хэдийн байгаа индексээс нийлмэл индекс гаргаж, барааны нийт үнийг хоёр дахь талбар болгон нэмбэл бид дахин 165 логик уншилт авах болно.

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

Энэ цуврал жишээг удаан хугацаанд үргэлжлүүлж болох ч энд хэлэхийг хүссэн хоёр гол санаа нь:

  • Хайлтын асуулгад шинэ шалгуур эсвэл эрэмбэлэх дарааллыг нэмэх нь хайлтын асуулгын хурдад ихээхэн нөлөөлнө.
  • Гэхдээ хэрэв бид хайлтын нэр томъёонд тохирох бүх үр дүнг биш харин зөвхөн нэг хэсгийг нь хасах шаардлагатай бол ийм асуулга оновчтой болгох олон арга бий.

Одоо хамгийн эхэнд дурдсан хоёр дахь асуулга руу шилжье - хайлтын шалгуурыг хангасан бичлэгийн тоог тоолдог. Үүнтэй ижил жишээг авч үзье - 100 доллараас дээш захиалга хайх:

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

Дээр дурдсан нийлмэл индексийг харгалзан бид дараахь зүйлийг олж авна.

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

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.

Дэд нийт талбар нь эхний байрлалд байхгүй тул асуулга үүнийг ашиглах боломжгүй тул асуулга бүхэл бүтэн индексээр дамждаг нь гайхмаар зүйл биш юм. Асуудлыг SubTotal талбарт өөр индекс нэмэх замаар шийдэж, үр дүнд нь зөвхөн 48 логик уншилтыг өгдөг.

Та тоо хэмжээг тоолох хүсэлтийн хэд хэдэн жишээг өгч болно, гэхдээ мөн чанар нь хэвээр байна: Мэдээллийн хэсгийг хүлээн авах, нийт дүнг тоолох нь үндсэндээ өөр хоёр хүсэлт юм, мөн тус бүр нь оновчтой болгохын тулд өөрийн арга хэмжээг шаарддаг. Ерөнхийдөө та хоёр асуулгад адилхан сайн ажилладаг индексүүдийн хослолыг олох боломжгүй болно.

Иймээс ийм хайлтын шийдлийг боловсруулахдаа тодруулах ёстой чухал шаардлагуудын нэг бол олдсон объектын нийт тоог харах нь бизнест үнэхээр чухал эсэх явдал юм. Үгүй гэдэг нь ихэвчлэн тохиолддог. Мөн тодорхой хуудасны дугаараар навигаци хийх нь миний бодлоор маш нарийн цар хүрээтэй шийдэл юм, учир нь ихэнх пейжинг хувилбарууд "дараагийн хуудас руу очих" шиг харагддаг.

2-р хуудасны сонголт

Хэрэглэгчид олдсон объектын нийт тоог мэдэх нь хамаагүй гэж бодъё. Хайлтын хуудсыг хялбарчлахыг хичээцгээе:

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд
Үнэн хэрэгтээ өөрчлөгдсөн цорын ганц зүйл бол тодорхой хуудасны дугаарууд руу шилжих ямар ч арга байхгүй бөгөөд одоо энэ хүснэгтийг харуулахын тулд хэдэн ширхэг байж болохыг мэдэх шаардлагагүй болно. Гэхдээ асуулт гарч ирнэ - хүснэгт нь дараагийн хуудсанд өгөгдөл байгаа эсэхийг яаж мэдэх вэ ("Дараах" холбоосыг зөв харуулахын тулд)?

Хариулт нь маш энгийн: та мэдээллийн сангаас харуулахад шаардагдахаас нэг бичлэгийг унших боломжтой бөгөөд энэ "нэмэлт" бичлэг байгаа нь дараагийн хэсэг байгаа эсэхийг харуулах болно. Ингэснээр та нэг хуудас өгөгдөл авахын тулд зөвхөн нэг хүсэлтийг ажиллуулах хэрэгтэй бөгөөд энэ нь гүйцэтгэлийг мэдэгдэхүйц сайжруулж, ийм функцийг дэмжихэд хялбар болгодог. Миний практикт нийт бичлэгийг тоолохоос татгалзсан нь үр дүнг 4-5 дахин хурдасгасан тохиолдол гарсан.

Энэ аргын хувьд хэрэглэгчийн интерфэйсийн хэд хэдэн сонголт байдаг: "буцах" ба "урагшаа" командууд, дээрх жишээн дээрх шиг "илүү ачаалах" товчлуур, энэ нь зүгээр л харуулсан үр дүнд шинэ хэсгийг нэмдэг "хязгааргүй гүйлгэх". "илүү их ачаалах" зарчмаар ажиллах боловч дараагийн хэсгийг авах дохио нь хэрэглэгч бүх харуулсан үр дүнг эцэс хүртэл гүйлгэх явдал юм. Харааны шийдэл нь ямар ч байсан, өгөгдлийн түүвэрлэлтийн зарчим ижил хэвээр байна.

Пэйжинг хэрэгжүүлэх нюансууд

Дээр өгөгдсөн бүх асуулгын жишээнүүд нь "офсет + тоолох" аргыг ашигладаг бөгөөд асуулга нь үр дүнгийн мөрүүдийг ямар дарааллаар, хэдэн мөрийг буцаах шаардлагатайг зааж өгдөг. Нэгдүгээрт, энэ тохиолдолд параметр дамжуулалтыг хэрхэн хамгийн сайн зохион байгуулахыг харцгаая. Практикт би хэд хэдэн аргыг олж мэдсэн:

  • Хүссэн хуудасны серийн дугаар (pageIndex), хуудасны хэмжээ (pageSize).
  • Буцааж өгөх эхний бичлэгийн серийн дугаар (startIndex), үр дүнгийн хамгийн их бичлэгийн тоо (тоо).
  • Буцах эхний бичлэгийн дарааллын дугаар (startIndex), буцааж өгөх сүүлчийн бичлэгийн дарааллын дугаар (endIndex).

Эхлээд харахад энэ нь маш энгийн зүйл тул ямар ч ялгаа байхгүй мэт санагдаж магадгүй юм. Гэхдээ энэ нь тийм биш юм - хамгийн тохиромжтой, бүх нийтийн сонголт бол хоёр дахь (startIndex, count) юм. Үүнд хэд хэдэн шалтгаан бий:

  • Дээр өгөгдсөн +1 оруулгыг засах аргын хувьд pageIndex болон pageSize-тэй эхний сонголт нь туйлын тохиромжгүй юм. Жишээлбэл, бид нэг хуудсанд 50 бичлэг харуулахыг хүсч байна. Дээрх алгоритмын дагуу та шаардлагатайгаас нэг бичлэгийг унших хэрэгтэй. Хэрэв энэ "+1" нь сервер дээр хэрэгжээгүй бол эхний хуудсанд 1-ээс 51 хүртэлх, хоёрдугаарт - 51-ээс 101 хүртэлх бичлэгийг хүсэх ёстой. Хэрэв та хуудасны хэмжээг 51-ээр зааж өгөөд pageIndex-ийг нэмэгдүүлбэл хоёр дахь хуудас нь 52-оос 102 хүртэл буцаж ирнэ гэх мэт. Үүний дагуу, эхний хувилбарт дараагийн хуудас руу шилжих товчлуурыг зөв хэрэгжүүлэх цорын ганц арга бол серверт "нэмэлт" мөрийг шалгах явдал бөгөөд энэ нь маш далд нюанс байх болно.
  • Гурав дахь сонголт нь огт утгагүй, учир нь ихэнх өгөгдлийн санд асуулга явуулахын тулд та сүүлийн бичлэгийн индекс биш харин тоолох шаардлагатай хэвээр байх болно. endIndex-ээс startIndex-ийг хасах нь энгийн арифметик үйлдэл байж болох ч энд илүүц байх болно.

Одоо бид "офсет + тоо хэмжээ" -ээр дамжуулан пейжинг хэрэгжүүлэх сул талуудыг тайлбарлах хэрэгтэй:

  • Дараагийн хуудас бүрийг сэргээх нь өмнөх хуудаснаас илүү үнэтэй бөгөөд удаан байх болно, учир нь мэдээллийн сан нь хайх, эрэмбэлэх шалгуурын дагуу "эхнээсээ" бүх бүртгэлийг үзэж, дараа нь хүссэн фрагмент дээрээ зогсох шаардлагатай хэвээр байх болно.
  • Бүх DBMS энэ хандлагыг дэмжиж чадахгүй.

Өөр хувилбарууд байдаг ч тэдгээр нь бас төгс бус байдаг. Эдгээр аргуудын эхнийх нь "keyset peging" эсвэл "seek method" гэж нэрлэгддэг бөгөөд дараах байдалтай байна: хэсгийг хүлээн авсны дараа та хуудасны сүүлийн бичлэгт байгаа талбарын утгыг санаж, дараа нь тэдгээрийг олж авахын тулд ашиглаж болно. дараагийн хэсэг. Жишээлбэл, бид дараах асуулга явуулсан.

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

Мөн сүүлийн бичлэгт бид захиалгын огнооны утгыг '2014-06-29' авсан. Дараа нь дараагийн хуудсыг авахын тулд та дараах зүйлийг хийж болно.

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

Асуудал нь OrderDate нь өвөрмөц бус талбар бөгөөд дээр заасан нөхцөл нь шаардлагатай олон мөрийг алдах магадлалтай юм. Энэ асуулгад хоёрдмол утгагүй байдлыг нэмэхийн тулд нөхцөл байдалд өвөрмөц талбар нэмэх шаардлагатай (75074 нь эхний хэсгийн үндсэн түлхүүрийн сүүлчийн утга гэж үзье):

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

Энэ сонголт зөв ажиллах боловч ерөнхийдөө нөхцөл нь OR операторыг агуулж байгаа тул оновчтой болгоход хэцүү байх болно. Захиалгын огноо нэмэгдэхийн хэрээр үндсэн түлхүүрийн утга нэмэгдэж байвал SalesOrderID-ээр зөвхөн шүүлтүүр үлдээснээр нөхцөлийг хялбарчилж болно. Гэхдээ үндсэн түлхүүрийн утгууд болон үр дүнг эрэмбэлэх талбарын хооронд хатуу хамаарал байхгүй бол ихэнх DBMS-д энэ OR-оос зайлсхийх боломжгүй. Миний мэдэх үл хамаарах зүйл бол Tuple харьцуулалтыг бүрэн дэмждэг PostgreSQL бөгөөд дээрх нөхцөлийг "ХАААН (OrderDate, SalesOrderID) < ('2014-06-29', 75074)" гэж бичиж болно. Эдгээр хоёр талбар бүхий нийлмэл түлхүүр өгсөн бол үүнтэй төстэй асуулга нь нэлээд хялбар байх ёстой.

Хоёрдахь өөр аргыг жишээлбэл, эндээс олж болно ElasticSearch гүйлгэх API буюу Космос DB - хүсэлт нь өгөгдлөөс гадна өгөгдлийн дараагийн хэсгийг авах боломжтой тусгай танигчийг буцааж өгөх үед. Хэрэв энэ танигчийн ашиглалтын хугацаа хязгааргүй бол (Comsos DB-ийн адил) энэ нь хуудасны хооронд дараалсан шилжилт хийх пейжинг хэрэгжүүлэх гайхалтай арга юм (дээр дурдсан сонголт №2). Үүний боломжит сул талууд: үүнийг бүх DBMS-д дэмждэггүй; Дараагийн хэсэг танигч нь хязгаарлагдмал ашиглалтын хугацаатай байж болох бөгөөд энэ нь хэрэглэгчийн харилцан үйлчлэлийг хэрэгжүүлэхэд ерөнхийдөө тохиромжгүй (ElasticSearch гүйлгэх API гэх мэт).

Нарийн төвөгтэй шүүлтүүр

Даалгаврыг улам хүндрүүлье. Онлайн дэлгүүрүүдээс хүн бүрт маш сайн мэддэг нүүр царай гэж нэрлэгддэг хайлтыг хэрэгжүүлэх шаардлага байна гэж бодъё. Захиалгын хүснэгтэд үндэслэсэн дээрх жишээнүүд нь энэ тохиолдолд тийм ч ойлгомжтой биш тул AdventureWorks мэдээллийн сангаас Бүтээгдэхүүний хүснэгт рүү шилжье:

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд
Талбайн эрэл хайгуулын цаад санаа юу вэ? Үнэн хэрэгтээ шүүлтүүр элемент бүрийн хувьд энэ шалгуурыг хангасан бичлэгийн тоог харуулсан болно бусад бүх ангилалд сонгосон шүүлтүүрүүдийг харгалзан үзэх.

Жишээлбэл, хэрэв бид энэ жишээн дээрх Дугуйн ангилал болон Хар өнгийг сонговол хүснэгтэд зөвхөн хар дугуй харагдах боловч:

  • Ангилал бүлгийн шалгуур бүрийн хувьд тухайн ангиллын бүтээгдэхүүний тоог хар өнгөөр ​​харуулах болно.
  • "Өнгө" бүлгийн шалгуур тус бүрийн хувьд энэ өнгийн дугуйн тоог харуулна.

Ийм нөхцөлд гарсан үр дүнгийн жишээ энд байна:

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд
Хэрэв та мөн "Хувцас" гэсэн ангилалыг шалгавал хүснэгтэд нөөцөд байгаа хар хувцас харагдах болно. "Өнгө" хэсэгт байгаа хар бүтээгдэхүүний тоог мөн шинэ нөхцлийн дагуу дахин тооцоолох бөгөөд зөвхөн "Ангилал" хэсэгт юу ч өөрчлөгдөхгүй ... Эдгээр жишээнүүд нь ердийн нүүр царайтай хайлтын алгоритмыг ойлгоход хангалттай гэж найдаж байна.

Одоо үүнийг харилцааны үндсэн дээр хэрхэн хэрэгжүүлж болохыг төсөөлье. Ангилал, Өнгө зэрэг бүлэг шалгуур тус бүрд тусдаа асуулга шаардлагатай болно:

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

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд

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

Хайлтын үр дүнгийн гаралт болон гүйцэтгэлийн асуудлууд
Энэ шийдэлд юу нь буруу байна вэ? Энэ нь маш энгийн - энэ нь тийм ч сайн биш юм. Шүүлтүүрийн хэсэг бүр тоо хэмжээг тооцоолохын тулд тусдаа асуулга шаарддаг бөгөөд эдгээр асуулга нь хамгийн хялбар биш юм. Онлайн дэлгүүрүүдэд зарим ангилалд хэдэн арван шүүлтүүрийн хэсэг байж болох бөгөөд энэ нь гүйцэтгэлийн ноцтой асуудал байж болно.

Ихэвчлэн эдгээр мэдэгдлийн дараа надад зарим шийдлүүдийг санал болгодог, тухайлбал:

  • Бүх тоон тоог нэг асуулгад нэгтгэнэ үү. Техникийн хувьд энэ нь UNION түлхүүр үгийг ашиглах боломжтой боловч энэ нь гүйцэтгэлд тийм ч их тус болохгүй - мэдээллийн сан нь фрагмент бүрийг эхнээс нь ажиллуулах шаардлагатай хэвээр байх болно.
  • Кэшийн тоо хэмжээ. Асуудлыг тайлбарлах болгондоо үүнийг надад санал болгодог. Анхааруулга гэвэл энэ нь ерөнхийдөө боломжгүй юм. Бидэнд 10 "нүүр", тус бүр нь 5 утгатай гэж бодъё. Энэ нь ижил онлайн дэлгүүрүүдээс харж болох зүйлтэй харьцуулахад маш "даруухан" нөхцөл байдал юм. Нэг фасет элементийн сонголт нь бусад 9-ийн хэмжигдэхүүнд нөлөөлдөг, өөрөөр хэлбэл шалгуур үзүүлэлт бүрийн хувьд хэмжигдэхүүн өөр өөр байж болно. Бидний жишээн дээр хэрэглэгч сонгох боломжтой нийт 50 шалгуур байдаг тул 250 боломжит хослолууд байх болно. Ийм массив өгөгдлийг дүүргэх санах ой, цаг хугацаа хангалтгүй. Энд та эсэргүүцэж, бүх хослолууд бодит биш бөгөөд хэрэглэгч 5-10-аас дээш шалгуурыг сонгох нь ховор гэж хэлж болно. Тийм ээ, залхуу ачаалж, зөвхөн сонгосон зүйлээ кэш хийх боломжтой, гэхдээ сонголт их байх тусам кэш нь үр ашиг багатай байх ба хариу үйлдэл үзүүлэх хугацаа нь мэдэгдэхүйц байх болно (ялангуяа өгөгдлийн багц тогтмол өөрчлөгддөг).

Аз болоход, ийм асуудал нь их хэмжээний өгөгдөл дээр урьдчилан таамаглах боломжтой нэлээд үр дүнтэй шийдлүүдтэй байсаар ирсэн. Эдгээр сонголтуудын аль нэгийн хувьд талуудын дахин тооцоолол, үр дүнгийн хуудсыг сервер рүү залгах хоёр зэрэгцээ дуудлага болгон хувааж, өгөгдлийг тал бүрээр нь ачаалах нь "саад гарахгүй" байхаар хэрэглэгчийн интерфэйсийг зохион байгуулах нь утга учиртай юм. Хайлтын үр дүн.

  • Аль болох ховор "нүүр" -ийг бүрэн дахин тооцоолохыг дууд. Жишээлбэл, хайлтын шалгуур өөрчлөгдөх болгонд бүгдийг дахин тооцоолж болохгүй, харин одоогийн нөхцөл байдалд тохирсон нийт үр дүнгийн тоог олж, хэрэглэгчээс харуулахыг хүсэх - "1425 бичлэг олдсон, харуулах уу?" Хэрэглэгч хайлтын нэр томъёог үргэлжлүүлэн өөрчлөх эсвэл "харуулах" товчийг дарах боломжтой. Зөвхөн хоёр дахь тохиолдолд л үр дүнг олж авах, тоо хэмжээг дахин тооцоолох хүсэлтийг бүх "талаар" биелүүлэх болно. Энэ тохиолдолд та хялбархан харж байгаачлан нийт үр дүнгийн тоо, түүнийг оновчтой болгох хүсэлтийг шийдвэрлэх шаардлагатай болно. Энэ аргыг олон жижиг онлайн дэлгүүрээс олж болно. Мэдээжийн хэрэг, энэ нь энэ асуудлыг шийдэх эм биш боловч энгийн тохиолдолд энэ нь сайн буулт байж болно.
  • Solr, ElasticSearch, Sphinx гэх мэт үр дүнг олох, тоолохын тулд хайлтын системийг ашиглана уу. Эдгээр нь бүгд "нүүр царайг" бүтээхэд зориулагдсан бөгөөд урвуу индексийн улмаас үүнийг нэлээд үр дүнтэй хийдэг. Хайлтын системүүд хэрхэн ажилладаг, яагаад ийм тохиолдолд ерөнхий зориулалтын мэдээллийн сангаас илүү үр дүнтэй байдаг, ямар дадлага, бэрхшээлүүд байдаг - энэ бол тусдаа нийтлэлийн сэдэв юм. Хайлтын систем нь үндсэн мэдээллийн санг орлох боломжгүй, үүнийг нэмэлт болгон ашигладаг: хайлтанд хамаарах үндсэн мэдээллийн санд гарсан аливаа өөрчлөлтийг хайлтын индекс рүү синхрончлоход анхаарлаа хандуулахыг хүсч байна; Хайлтын систем нь ихэвчлэн зөвхөн хайлтын системтэй харилцаж, үндсэн мэдээллийн санд ханддаггүй. Энд байгаа хамгийн чухал цэгүүдийн нэг бол энэхүү синхрончлолыг хэрхэн найдвартай зохион байгуулах явдал юм. Энэ бүхэн нь "урвалын хугацаа" -ын шаардлагаас хамаарна. Хэрэв үндсэн мэдээллийн баазын өөрчлөлт ба түүний хайлт дахь "илэрхийлэл" хоорондын хугацаа тийм ч чухал биш бол та саяхан өөрчлөгдсөн бүртгэлийг хэдэн минут тутамд хайж, индексжүүлдэг үйлчилгээг үүсгэж болно. Хэрэв та хамгийн богино хугацаанд хариу өгөхийг хүсч байвал иймэрхүү зүйлийг хэрэгжүүлж болно гүйлгээний гадагшаа хайрцаг хайлтын үйлчилгээ рүү шинэчлэлтүүдийг илгээх.

үр дүн нь

  1. Сервер талын пейжинг хэрэгжүүлэх нь ихээхэн төвөгтэй бөгөөд зөвхөн хурдацтай хөгжиж буй эсвэл зүгээр л том өгөгдлийн багцад л ач холбогдолтой юм. "Том" эсвэл "хурдан хөгжиж буй" гэдгийг хэрхэн үнэлэх талаар яг нарийн жор байдаггүй, гэхдээ би дараах аргыг баримтална.
    • Хэрэв серверийн цаг, сүлжээний дамжуулалтыг харгалзан бүрэн мэдээллийн цуглуулгыг хүлээн авах нь гүйцэтгэлийн шаардлагад нийцэж байгаа бол серверийн тал дээр пейджинг хийх нь утгагүй болно.
    • Мэдээлэл бага боловч мэдээлэл цуглуулах хэмжээ байнга нэмэгдэж байгаа тул ойрын ирээдүйд гүйцэтгэлийн асуудал гарахгүй байх нөхцөл байдал үүсч магадгүй юм. Хэрэв ирээдүйд зарим багц өгөгдлүүд өмнөх цэгийг хангахаа больсон бол пейжинг шууд эхлүүлэх нь дээр.
  2. Хэрэв бизнесийн зүгээс нийт үр дүнг харуулах эсвэл хуудасны дугаарыг харуулах хатуу шаардлага байхгүй, таны систем хайлтын системгүй бол эдгээр цэгүүдийг хэрэгжүүлэхгүй байж, 2-р сонголтыг авч үзэх нь дээр.
  3. Хэрэв талбарт хайлт хийх тодорхой шаардлага байгаа бол гүйцэтгэлийг алдагдуулахгүйгээр танд хоёр сонголт байна:
    • Хайлтын шалгуур өөрчлөгдөх бүрт бүх хэмжигдэхүүнийг дахин тооцоолж болохгүй.
    • Solr, ElasticSearch, Sphinx болон бусад хайлтын системийг ашигла. Гэхдээ энэ нь үндсэн мэдээллийн санг орлох боломжгүй бөгөөд хайлтын асуудлыг шийдвэрлэх үндсэн хадгалалтын нэмэлт болгон ашиглах ёстой гэдгийг ойлгох хэрэгтэй.
  4. Түүнчлэн, нүүр царайтай хайлтын хувьд хайлтын үр дүнгийн хуудас болон тооллогыг хоёр зэрэгцээ хүсэлт болгон хуваах нь зүйтэй юм. Хэмжигдэхүүнийг тоолох нь үр дүнг авахаас илүү урт хугацаа шаардагдах боловч үр дүн нь хэрэглэгчдэд илүү чухал байдаг.
  5. Хэрэв та хайлт хийхдээ SQL мэдээллийн санг ашиглаж байгаа бол энэ хэсэгтэй холбоотой аливаа кодын өөрчлөлтийг зохих хэмжээний өгөгдлийн гүйцэтгэлийг сайтар шалгаж үзэх хэрэгтэй (шууд мэдээллийн сан дахь хэмжээнээс хэтэрсэн). Мэдээллийн сангийн бүх тохиолдлууд, ялангуяа "шууд" дээр асуулга гүйцэтгэх хугацааг хянахыг зөвлөж байна. Хөгжлийн үе шатанд асуулгын төлөвлөгөөнд бүх зүйл хэвийн байсан ч өгөгдлийн хэмжээ өсөх тусам нөхцөл байдал мэдэгдэхүйц өөрчлөгдөж магадгүй юм.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх