PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Би танд Владимир Ситниковын 2016 оны эхэн үеийн "PostgreSQL болон JDBC бүх шүүсийг шахаж байна" тайлангийн хуулбарыг уншихыг санал болгож байна.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Өдрийн мэнд Намайг Владимир Ситников гэдэг. Би NetCracker-д 10 жил ажиллаж байна. Тэгээд би бүтээмжид голчлон анхаардаг. Java-тэй холбоотой бүх зүйл, SQL-тэй холбоотой бүх зүйл миний дуртай зүйл.

Өнөөдөр би PostgreSQL-ийг мэдээллийн сангийн сервер болгон ашиглаж эхлэхэд компанид юу тохиолдсон тухай ярих болно. Мөн бид ихэвчлэн Java-тэй ажилладаг. Гэхдээ өнөөдөр та нарт хэлэх гэж байгаа зүйл бол зөвхөн Java-ийн тухай биш юм. Практикаас харахад энэ нь бусад хэл дээр ч тохиолддог.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Бид ярих болно:

  • өгөгдлийн түүвэрлэлтийн талаар.
  • Өгөгдөл хадгалах тухай.
  • Мөн гүйцэтгэлийн талаар.
  • Мөн тэнд булсан усан доорх тармууруудын тухай.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Энгийн асуултаар эхэлцгээе. Бид үндсэн түлхүүр дээр үндэслэн хүснэгтээс нэг мөр сонгоно.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Мэдээллийн сан нь нэг хост дээр байрладаг. Мөн энэ бүх тариалалтад 20 миллисекунд шаардлагатай.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Эдгээр 20 миллисекунд нь маш их юм. Хэрэв танд 100 ийм хүсэлт байгаа бол та эдгээр хүсэлтийг гүйлгэн үзэхэд секунд тутамд цаг зарцуулдаг, өөрөөр хэлбэл бид цаг алдаж байна.

Бид үүнийг хийх дургүй бөгөөд бааз бидэнд юу санал болгож байгааг хардаг. Өгөгдлийн сан нь бидэнд асуулга гүйцэтгэх хоёр сонголтыг санал болгодог.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Эхний сонголт бол энгийн хүсэлт юм. Энэ нь юугаараа сайн бэ? Бид үүнийг аваад илгээдэг, өөр юу ч биш.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

https://github.com/pgjdbc/pgjdbc/pull/478

Мэдээллийн сан нь илүү төвөгтэй боловч илүү ажиллагаатай дэвшилтэт асуулгатай. Та задлан шинжлэх, гүйцэтгэх, хувьсагч холбох гэх мэт хүсэлтийг тусад нь илгээж болно.

Супер өргөтгөсөн асуулга нь бидний одоогийн тайланд тусгагдаагүй зүйл юм. Бид мэдээллийн сангаас ямар нэг зүйлийг хүсч байгаа бөгөөд ямар нэгэн хэлбэрээр бий болсон хүслийн жагсаалт байдаг, өөрөөр хэлбэл энэ бол бидний хүсч байгаа зүйл боловч одоо болон дараа жил нь боломжгүй юм. Тиймээс бид үүнийг зүгээр л бичсэн бөгөөд бид гол хүмүүсийг сэгсэрнэ.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Мөн бидний хийж чадах зүйл бол энгийн асуулга болон өргөтгөсөн асуулга юм.

Арга тус бүрийн онцлог нь юу вэ?

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Өргөтгөсөн асуулга - задлан шинжлэхэд цаг хэмнэх боломжийг танд олгоно. Энэ бол бидний хийсэн зүйл бөгөөд ашиглаж эхэлсэн. Энэ нь бидэнд үнэхээр тусалсан. Зөвхөн задлан шинжлэхэд хэмнэлт гарахгүй. Мэдээлэл дамжуулахад хэмнэлт бий. Хоёртын форматаар өгөгдөл дамжуулах нь илүү үр дүнтэй байдаг.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Дасгал руугаа явцгаая. Ердийн програм иймэрхүү харагдаж байна. Энэ нь Java гэх мэт байж болно.

Бид мэдэгдэл гаргасан. Тушаалыг гүйцэтгэсэн. Ойролцоогоор үүсгэсэн. Энд алдаа хаана байна вэ? Асуудал юу вэ? Асуудалгүй. Бүх номонд ингэж бичсэн байдаг. Ингэж бичих ёстой. Хэрэв та хамгийн их гүйцэтгэлийг хүсч байвал ингэж бичээрэй.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Гэвч энэ нь үр дүнд хүрэхгүй гэдгийг практик харуулж байна. Яагаад? Яагаад гэвэл бид "ойрхон" аргатай. Бид үүнийг хийх үед мэдээллийн сангийн үүднээс харахад энэ нь мэдээллийн сантай ажилладаг тамхичинтай адил юм. Бид "PARSE EXECUTE DEALLOCATE" гэж хэлсэн.

Яагаад энэ бүх нэмэлт мэдүүлэг үүсгэж, буулгаж байна вэ? Тэд хэнд ч хэрэггүй. Гэхдээ PreparedStatements-д ихэвчлэн тохиолддог зүйл бол бид тэдгээрийг хаахад тэд мэдээллийн сан дээрх бүх зүйлийг хаадаг. Энэ бол бидний хүсч байгаа зүйл биш юм.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Бид эрүүл хүмүүс шиг баазтай ажиллахыг хүсч байна. Бид нэг удаа мэдүүлгээ аваад, дараа нь олон удаа гүйцэтгэсэн. Үнэн хэрэгтээ олон удаа - энэ нь хэрэглээний бүх хугацаанд нэг удаа тохиолддог - тэдгээрийг задлан шинжилдэг. Мөн бид өөр өөр REST дээр ижил мэдэгдлийн id ашигладаг. Энэ бол бидний зорилго.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Бид үүнд хэрхэн хүрэх вэ?

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Энэ нь маш энгийн - мэдэгдлийг хаах шаардлагагүй. Бид үүнийг ингэж бичдэг: "бэлтгэх" "гүйцэтгэх".

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

Ийм алдааг амархан засдаг нь ойлгомжтой. Би тэдний тухай ярихгүй. Гэхдээ шинэ хувилбар нь илүү хурдан ажилладаг гэж би хэлэх болно. Энэ арга нь тэнэг, гэхдээ одоо ч гэсэн.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Хэрхэн зөв ажиллах вэ? Үүний тулд бид юу хийх хэрэгтэй вэ?

Бодит байдал дээр програмууд үргэлж мэдэгдлүүдийг хаадаг. Бүх номон дээр үүнийг хаа гэж хэлдэг, тэгэхгүй бол санах ой нь урсах болно.

PostgreSQL нь асуулга хэрхэн кэш хийхээ мэддэггүй. Сеанс бүр энэ кэшийг өөртөө бий болгох шаардлагатай.

Мөн бид задлан шинжлэхэд цаг үрмээргүй байна.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Мөн бид ердийнх шиг хоёр сонголттой.

Эхний сонголт бол бид үүнийг аваад PgSQL-д бүгдийг боож өгье гэж хэлэх явдал юм. Тэнд кэш байна. Энэ нь бүх зүйлийг кэш болгодог. Энэ нь гайхалтай болно. Бид үүнийг харсан. Бидэнд 100500 хүсэлт байна. Ажиллахгүй байна. Бид хүсэлтийг гараар журам болгохыг зөвшөөрөхгүй. Үгүй үгүй.

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

https://github.com/pgjdbc/pgjdbc/pull/319

Энэ нь 2015 оны XNUMX-р сард гарч ирсэн. Одоо илүү орчин үеийн хувилбар байна. Мөн бүх зүйл гайхалтай. Энэ нь маш сайн ажилладаг тул бид програмд ​​юу ч өөрчлөхгүй. Мөн бид PgSQL-ийн талаар бодохоо ч больсон, өөрөөр хэлбэл энэ нь бүх нэмэлт зардлыг бараг тэг болгон бууруулахад хангалттай байсан.

Үүний дагуу нэг удаагийн хүсэлт бүрт мэдээллийн санд санах ойг дэмий үрэхгүйн тулд серверээс бэлтгэсэн мэдэгдлүүд 5 дахь гүйцэтгэл дээр идэвхждэг.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Та асууж магадгүй - тоонууд хаана байна? Та юу авч байна вэ? Энд би тоо өгөхгүй, учир нь хүсэлт бүр өөрийн гэсэн байдаг.

Бидний асуулга OLTP асуулгад задлан шинжлэхэд ойролцоогоор 20 миллисекунд зарцуулсан. Гүйцэтгэхэд 0,5 миллисекунд, задлан шинжлэхэд 20 миллисекунд байсан. Хүсэлт - 10 киб текст, 170 мөр төлөвлөгөө. Энэ бол OLTP хүсэлт юм. Энэ нь 1, 5, 10 мөр, заримдаа илүү ихийг шаарддаг.

Гэхдээ бид 20 миллисекундыг дэмий үрэхийг огт хүсээгүй. Бид үүнийг 0 болгон бууруулсан. Бүх зүйл сайхан байна.

Та эндээс юу авч болох вэ? Хэрэв танд Java байгаа бол жолоочийн орчин үеийн хувилбарыг аваад баярлах болно.

Хэрэв та өөр хэлээр ярьдаг бол бодоорой - магадгүй танд энэ хэрэгтэй юу? Учир нь эцсийн хэлний үүднээс авч үзвэл, жишээлбэл, PL 8 эсвэл танд LibPQ байгаа бол та гүйцэтгэлд биш, задлан шинжлэхэд цаг зарцуулж байгаа нь тодорхойгүй бөгөөд үүнийг шалгах нь зүйтэй юм. Хэрхэн? Бүх зүйл үнэгүй.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Хэрэв хүсэлт нь динамикаар үүсгэгдсэн бол. Энэ нь тохиолддог. Хэн нэгэн мөрүүдийг хооронд нь нааж, SQL асуулга үүснэ.

Тэр яагаад муу юм бэ? Энэ нь муу, учир нь бид дуусах болгондоо өөр утсаар дуусдаг.

Мөн энэ өөр мөрийн hashCode-ийг дахин унших шаардлагатай. Энэ бол үнэхээр CPU-ийн ажил юм - одоо байгаа хэш доторх урт хүсэлтийн текстийг олох нь тийм ч хялбар биш юм. Тиймээс, дүгнэлт нь энгийн байдаг - хүсэлтийг бүү үүсгэ. Тэдгээрийг нэг хувьсагчаар хадгал. Бас баярла.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Дараагийн асуудал. Өгөгдлийн төрлүүд чухал. Ямар төрлийн NULL байх нь хамаагүй, ямар нэгэн төрөл байг гэж хэлдэг ORM-ууд байдаг. Хэрэв Int бол бид setInt гэж хэлнэ. Хэрэв NULL байвал үргэлж VARCHAR байг. Тэгээд эцэст нь NULL гэж юу байх нь ямар ялгаатай вэ? Мэдээллийн сан өөрөө бүх зүйлийг ойлгох болно. Мөн энэ зураг ажиллахгүй байна.

Практикт мэдээллийн сан огт хамаагүй. Хэрэв та эхний удаад үүнийг тоо гэж хэлсэн бол хоёр дахь удаагаа VARCHAR гэж хэлсэн бол Серверийн бэлтгэсэн мэдэгдлийг дахин ашиглах боломжгүй. Мөн энэ тохиолдолд бид мэдэгдлээ дахин үүсгэх ёстой.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Хэрэв та ижил асуулга явуулж байгаа бол баганад байгаа өгөгдлийн төрлүүд нь андуураагүй эсэхийг шалгаарай. Та NULL-г анхаарах хэрэгтэй. Энэ бол PreparedStatements-ийг ашиглаж эхэлсний дараа бидэнд тохиолддог нийтлэг алдаа юм

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

За, асаав. Магадгүй тэд жолоочийг авч явсан байх. Тэгээд бүтээмж буурсан. Байдал муудлаа.

Энэ яаж болдог вэ? Энэ алдаа эсвэл онцлог уу? Харамсалтай нь энэ нь алдаа эсвэл онцлог шинж гэдгийг ойлгох боломжгүй байсан. Гэхдээ энэ асуудлыг дахин гаргах маш энгийн хувилбар бий. Тэр биднийг гэнэтийн байдлаар отолтонд оруулав. Мөн энэ нь нэг хүснэгтээс шууд утгаараа дээж авахаас бүрдэнэ. Бидэнд мэдээж ийм хүсэлт илүү ирсэн. Дүрмээр бол тэд хоёр, гурван хүснэгтийг багтаасан боловч ийм тоглуулах хувилбар байдаг. Өгөгдлийн сангаасаа дурын хувилбарыг аваад тоглуулаарай.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Гол нь бид хоёр баганатай бөгөөд тус бүр нь индексжүүлсэн байна. Нэг NULL баганад сая мөр байна. Хоёрдахь баганад ердөө 20 мөр л байна. Бид хязгаарлагдмал хувьсагчгүйгээр ажиллахад бүх зүйл сайн ажилладаг.

Хэрэв бид хязгаарлагдмал хувьсагчдыг ажиллуулж эхэлбэл, өөрөөр хэлбэл "?" эсвэл бидний хүсэлтийг "$1" гэж үзвэл бид юу авах вэ?

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Эхний гүйцэтгэл нь хүлээгдэж буй шиг байна. Хоёр дахь нь арай хурдан юм. Ямар нэг зүйл хадгалагдсан байна. Гурав, дөрөв, тав. Дараа нь bang - мөн үүнтэй төстэй зүйл. Хамгийн аймшигтай нь энэ нь зургаа дахь цаазаар авах үед тохиолддог. Бодит гүйцэтгэлийн төлөвлөгөө юу болохыг ойлгохын тулд яг зургаан цаазаар авах шаардлагатай гэдгийг хэн мэдлээ?

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

Та энэ талаар юу хийж чадах вэ? Энд мэдээжийн хэрэг ямар нэгэн зүйлийг таамаглахад илүү хэцүү байдаг. Бидний ашигладаг энгийн шийдэл байдаг. Энэ нь +0, OFFSET 0. Та ийм шийдлүүдийг мэдэх нь гарцаагүй. Бид зүгээр л аваад хүсэлтэд "+0" нэмээд бүх зүйл хэвийн байна. Би чамд дараа үзүүлье.

Мөн өөр нэг сонголт бий - төлөвлөгөөг илүү анхааралтай ажигла. Хөгжүүлэгч нь зөвхөн хүсэлт бичихээс гадна "шинжилгээг тайлбарла" гэж 6 удаа хэлэх ёстой. Хэрэв 5 бол энэ нь ажиллахгүй болно.

Гурав дахь сонголт байна - pgsql-хакеруудад захидал бичээрэй. Би бичсэн, гэхдээ энэ нь алдаа эсвэл онцлог эсэх нь тодорхойгүй байна.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

Энэ нь хэр их боломжтой юм шиг санагдаж байна? Энд алдаа байна, тэнд алдаа байна. Үнэндээ алдаа хаа сайгүй байдаг.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Илүү дэлгэрэнгүй харцгаая. Жишээлбэл, бидэнд хоёр схем байна. S хүснэгттэй А схем, S хүснэгттэй Б диаграмм. Query - хүснэгтээс өгөгдлийг сонгох. Энэ тохиолдолд бидэнд юу байх вэ? Бидэнд алдаа гарна. Бид дээр дурдсан бүх зүйлийг авах болно. Дүрэм бол алдаа хаа сайгүй байдаг тул дээр дурдсан бүх зүйл бидэнд байх болно.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Одоо асуулт бол: "Яагаад?" Хэрэв бидэнд схем байгаа бол хүснэгтийг хаанаас хайхыг зааж өгдөг "хайлтын_зам" хувьсагч байдаг гэсэн баримт бичиг байгаа бололтой. Хувьсагч байгаа юм шиг санагдаж байна.

Асуудал юу вэ? Асуудал нь серверээс бэлтгэсэн мэдэгдлүүд нь хайлтын_замыг хэн нэгэн өөрчилж болно гэж сэжиглэдэггүй явдал юм. Энэ утга нь мэдээллийн сангийн хувьд тогтмол хэвээр байна. Мөн зарим хэсэг нь шинэ утгыг олж авахгүй байж магадгүй юм.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Мэдээжийн хэрэг, энэ нь таны туршиж буй хувилбараас хамаарна. Таны хүснэгтүүд хэр зэрэг ялгаатай байгаагаас хамаарна. Мөн 9.1 хувилбар нь хуучин хүсэлтүүдийг гүйцэтгэх болно. Шинэ хувилбарууд нь алдааг илрүүлж, танд алдаа байна гэж хэлж болно.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Search_path + серверээс бэлтгэсэн мэдэгдлүүдийг = тохируулах
кэш төлөвлөгөө нь үр дүнгийн төрлийг өөрчлөх ёсгүй

Үүнийг яаж эмчлэх вэ? Энгийн жор байдаг - үүнийг бүү хий. Аппликешн ажиллаж байх үед хайлтын_замыг өөрчлөх шаардлагагүй. Хэрэв та өөрчлөгдвөл шинэ холболт үүсгэх нь дээр.

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

Би дахин онцлон хэлье - энэ бол Java-д ердийн зүйл биш юм. Бид PL/pgSQL дээр ижил зүйлийг нэг нэгээр нь харах болно. Гэхдээ тэнд хуулбарлана.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Дата сонгохыг оролдъё. Бид сонгож, сонгодог. Бидэнд нэг сая эгнээ бүхий хүснэгт бий. Мөр бүр нь килобайт байна. Ойролцоогоор гигабайт өгөгдөл. Мөн бид Java машинд 128 мегабайт ажиллах санах ойтой.

Бид бүх номонд зөвлөсний дагуу урсгал боловсруулалтыг ашигладаг. Өөрөөр хэлбэл, бид resultSet-ийг нээж, тэндээс өгөгдлийг бага багаар уншина. Энэ нь ажиллах уу? Энэ нь санах ойгоос унах уу? Жаахан унших уу? Мэдээллийн санд итгэцгээе, Postgres-д итгэцгээе. Бид үүнд итгэхгүй байна. Бид Санах ойноосоо унах уу? OutOfMemory-г хэн үзсэн бэ? Үүний дараа хэн үүнийг засч чадсан бэ? Хэн нэгэн үүнийг засч залруулж чадсан.

Хэрэв та сая эгнээтэй бол зүгээр л сонгож болохгүй. OFFSET/LIMIT шаардлагатай. Энэ сонголтыг хэн сонгох вэ? Мөн autoCommit-тэй тоглохыг хэн дэмждэг вэ?

Энд ердийнх шиг хамгийн гэнэтийн сонголт зөв болж хувирав. Хэрэв та гэнэт autoCommit-ийг унтраавал энэ нь туслах болно. Яагаад тэр вэ? Шинжлэх ухаан энэ талаар мэдэхгүй.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Гэхдээ анхдагч байдлаар Postgres мэдээллийн санд холбогдсон бүх үйлчлүүлэгчид өгөгдлийг бүхэлд нь татаж авдаг. PgJDBC нь энэ талаар үл хамаарах зүйл биш бөгөөд бүх мөрийг сонгодог.

FetchSize-ийн сэдэвт өөрчлөлт бий, өөрөөр хэлбэл та эндээс өгөгдлийг 10, 50-аар сонгоно уу гэж тусдаа мэдэгдлийн түвшинд хэлж болно. Гэхдээ та autoCommit-г унтраах хүртэл энэ нь ажиллахгүй. AutoCommit-г унтраасан - энэ нь ажиллаж эхэлнэ.

Гэхдээ кодыг судалж, setFetchSize-г тохируулах нь хаа сайгүй тохиромжгүй юм. Тиймээс бид бүх холболтын үндсэн утгыг хэлэх тохиргоог хийсэн.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Мэдээжийн хэрэг, та үүнийг байтаар хэрхэн хязгаарлах талаар сурах хэрэгтэй, гэхдээ жор нь ийм байна: defaultRowFetchSize-г зуугаас дээш болгож, аз жаргалтай байгаарай.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Өгөгдөл оруулах руугаа явцгаая. Оруулах нь илүү хялбар, өөр өөр сонголтууд байдаг. Жишээлбэл, INSERT, VALUES. Энэ бол сайн сонголт юм. Та "INSERT SELECT" гэж хэлж болно. Практикт энэ нь ижил зүйл юм. Гүйцэтгэлийн хувьд ямар ч ялгаа байхгүй.

Номууд нь Багцын мэдэгдлийг гүйцэтгэх хэрэгтэй гэж бичсэн байдаг бол номууд нь хэд хэдэн хаалтанд илүү төвөгтэй командуудыг гүйцэтгэх боломжтой гэж бичсэн байдаг. Postgres нь гайхалтай онцлогтой - та COPY хийх боломжтой, өөрөөр хэлбэл үүнийг илүү хурдан хийх боломжтой.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Хэрэв та үүнийг хэмжвэл та дахин сонирхолтой нээлтүүдийг хийж чадна. Үүнийг бид хэрхэн ажиллахыг хүсч байна вэ? Бид задлан шинжлэхгүй, шаардлагагүй командуудыг гүйцэтгэхгүй байхыг хүсч байна.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Тиймээс үйлчлүүлэгч үе үе синхрончлолын багц илгээхээс өөр аргагүй болдог. Нэмэлт сүлжээний харилцан үйлчлэл, нэмэлт цаг хугацаа.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир СитниковМөн бид тэдгээрийг нэмэх тусам улам дорддог. Жолооч нь нэлээд гутранги үзэлтэй бөгөөд шугамын хэмжээ гэх мэтээс хамааран 200 мөр тутамд нэг удаа нэмдэг.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

https://github.com/pgjdbc/pgjdbc/pull/380

Зөвхөн нэг мөрийг засахад бүх зүйл 10 дахин хурдасна. Энэ нь тохиолддог. Яагаад? Ердийнх шиг ийм тогтмолыг аль хэдийн хаа нэгтээ ашиглаж байсан. Мөн "128" гэсэн утга нь багцыг ашиглахгүй гэсэн үг юм.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Java бичил жишиг морины хэрэгсэл

Үүнийг албан ёсны хувилбарт оруулаагүй нь сайн хэрэг. Гаргаж эхлэхээс өмнө илрүүлсэн. Миний өгсөн бүх утга нь орчин үеийн хувилбарууд дээр үндэслэсэн болно.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Үүнийг өмсөж үзэцгээе. Бид InsertBatch-ийг энгийн хэмждэг. Бид InsertBatch-ийг олон удаа хэмждэг, өөрөөр хэлбэл ижил зүйл боловч олон утгууд байдаг. Амаргүй хөдөлгөөн. Хүн бүр үүнийг хийж чадахгүй, гэхдээ энэ нь COPY-ээс хамаагүй хялбар, маш энгийн алхам юм.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Та COPY хийж болно.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Мөн та үүнийг бүтэц дээр хийж болно. Хэрэглэгчийн анхдагч төрлийг зарлаж, массив дамжуулж, хүснэгтэд шууд INSERT хийнэ.

Хэрэв та pgjdbc/ubenchmsrk/InsertBatch.java холбоосыг нээвэл энэ код GitHub дээр байна. Та тэнд ямар хүсэлтүүд үүссэнийг тусгайлан харж болно. Энэ хамаагүй.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

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

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Бид өгөгдөл оруулдаг. Энэ бол маш энгийн ширээ юм. Гурван багана. Тэгээд бид энд юу харж байна вэ? Эдгээр гурван хувилбарыг ойролцоогоор харьцуулж болно гэдгийг бид харж байна. Мөн COPY бол мэдээж илүү сайн.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Энэ нь бид хэсгүүдийг оруулах үед юм. Бид нэг VALUES утга, хоёр VALUES утга, гурван VALUES утга гэж хэлэхэд эсвэл тэдгээрийн 10-ыг нь таслалаар тэмдэглэсэн. Энэ одоо зүгээр л хэвтээ байна. 1, 2, 4, 128. Цэнхэр өнгөөр ​​зурсан Багцын оруулга нь түүнд маш сайхан мэдрэмж төрүүлдэг нь харагдаж байна. Өөрөөр хэлбэл, та нэг нэгээр нь оруулах юм уу, эсвэл нэг дор дөрвийг оруулахад ч гэсэн бид ҮНЭ ЦЭНЭ-т бага зэрэг шахагдсан учраас энэ нь хоёр дахин сайн болдог. Цөөн ГҮЙЦЭТГЭХ үйлдлүүд.

COPY-г бага хэмжээгээр ашиглах нь туйлын найдваргүй юм. Эхний хоёр дээр нь ч зураагүй. Тэд диваажинд очдог, өөрөөр хэлбэл COPY-д зориулж эдгээр ногоон тоонууд.

Доод тал нь зуун мөр өгөгдөлтэй үед COPY-г ашиглах хэрэгтэй. Энэ холболтыг нээх зардал их байна. Үнэнийг хэлэхэд би энэ чиглэлд ухаагүй. Би Багцыг оновчтой болгосон боловч COPY биш.

Бид дараа нь юу хийх вэ? Бид үүнийг туршиж үзсэн. Бид бүтэц, эсвэл хэд хэдэн утгыг хослуулсан ухаалаг бактыг ашиглах хэрэгтэй гэдгийг бид ойлгож байна.

PostgreSQL болон JDBC нь бүх шүүсийг шахаж гаргадаг. Владимир Ситников

Өнөөдрийн илтгэлээс та юу авчрах ёстой вэ?

  • PreparedStatement бол бидний бүх зүйл юм. Энэ нь бүтээмжийн хувьд маш их зүйлийг өгдөг. Энэ нь тосонд том хэмжээний флоп үүсгэдэг.
  • Мөн та 6 удаа ТАЙЛБАРТАЙ ШИНЖИЛГЭЭ хийх хэрэгтэй.
  • Асуудалтай асуултуудын үлдсэн хувийг засахын тулд бид OFFSET 0, +0 гэх мэт заль мэхийг шингэлэх хэрэгтэй.

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

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