ບັນຫາ N+1 Query ແມ່ນຮູບແບບຕ້ານປະສິດທິພາບ (anti-pattern) ດ້ານປະສິດທິພາບ ທີ່ເກີດຂຶ້ນເມື່ອດຶງຂໍ້ມູນລາຍການດ້ວຍ query ຄັ້ງດຽວ ແລ້ວຕາມດ້ວຍການດຶງຂໍ້ມູນທີ່ກ່ຽວຂ້ອງຂອງແຕ່ລະ record ທີລະລາຍການແຍກກັນ ສົ່ງຜົນໃຫ້ມີການເຂົ້າເຖິງຖານຂໍ້ມູນທັງໝົດ N+1 ຄັ້ງ.
ເມື່ອໃຊ້ ORM (Object-Relational Mapping) ຫຼື query builder, ມັກຈະເກີດບັນຫານີ້ໂດຍບໍ່ຮູ້ຕົວ. ຮູບແບບຂອງມັນເປັນດັ່ງນີ້:
ຍົກຕົວຢ່າງ, ລອງຄິດເຖິງກໍລະນີທີ່ສະແດງໜ້າລາຍການຄຳສັບ. ທຳອິດ SELECT 50 ລາຍການຈາກ table glossaries, ຈາກນັ້ນດຶງຂໍ້ມູນການແປຂອງແຕ່ລະຄຳສັບຈາກ table translations ທີລະລາຍການ, ລວມແລ້ວຈະມີ query ທັງໝົດ 51 ຄັ້ງ. ຖ້າຈຳນວນລາຍການເພີ່ມເປັນ 500, ກໍຈະເຮັດ 501 ຄັ້ງ.
ເຖິງແມ່ນວ່າແຕ່ລະ query ຈະຕອບສະໜອງພາຍໃນໄລຍະສອງສາມ millisecond, ແຕ່ເນື່ອງຈາກຈຳນວນຄັ້ງເພີ່ມຂຶ້ນແບບ linear, response time ຈຶ່ງຊຸດໂຊມລົງຕາມສັດສ່ວນຂອງປະລິມານຂໍ້ມູນ. table ທີ່ໃນ local development ມີພຽງສອງສາມສິບລາຍການ ອາດຂະຫຍາຍເປັນຫຼາຍພັນລາຍການໃນ production ແລ້ວຄ່ອຍສະແດງໃຫ້ເຫັນຄວາມຊ້າ — ອຸບັດຕິເຫດແບບນີ້ບໍ່ແມ່ນເລື່ອງແປກ.
ຍິ່ງໄປກວ່ານັ້ນ, ໃນສະພາບແວດລ້ອມທີ່ DB server ແລະ application server ຖືກແຍກອອກຈາກກັນຜ່ານ network, overhead ຂອງ round trip ຈະສະສົມຕາມຈຳນວນຄັ້ງ. ເຖິງແມ່ນ query ເອງຈະເບົາ, ແຕ່ network latency ກໍຈະກາຍເປັນຕົວຊີ້ຂາດ.
ວິທີແກ້ໄຂທີ່ເປັນຕົວແທນສາມາດແບ່ງອອກເປັນ 2 ປະເພດຫຼັກ ຄື eager loading (ການໂຫຼດລ່ວງໜ້າ) ແລະ JOIN.
| ວິທີການ | ຕົວຢ່າງ framework | ສະຫຼຸບ |
|---|---|---|
| eager loading | includes ຂອງ Rails / select_related ຂອງ Django / include ຂອງ Prisma | ORM ສ້າງ query ສຳລັບດຶງຂໍ້ມູນທີ່ກ່ຽວຂ້ອງໂດຍອັດຕະໂນມັດ |
| explicit JOIN | raw SQL / .select("*, children(*)") ຂອງ Supabase | ສົ່ງຄືນ parent ແລະ child ໂດຍການ join ໃນ query ດຽວ |
| DataLoader pattern | DataLoader ຂອງ GraphQL / cache() ຂອງ Next.js | ລວບລວມ key ພາຍໃນ request ແລ້ວປ່ຽນເປັນ batch query |
ໃນກໍລະນີທີ່ໃຊ້ Supabase, ການໃຊ້ embedded query ຂອງ PostgREST (select("*, translations(*)")) ຊ່ວຍໃຫ້ດຶງຂໍ້ມູນທີ່ກ່ຽວຂ້ອງໄດ້ໃນ 1 request ໂດຍບໍ່ຕ້ອງຂຽນ loop ຢູ່ຝ່າຍ application.
ເພື່ອກວດຫາ N+1 ໃນຂັ້ນຕອນການພັດທະນາ, ການຕິດຕາມ query log ແມ່ນມີປະສິດທິພາບ. ສຳລັບ PostgreSQL, ສາມາດຕັ້ງ log_min_duration_statement ເປັນ 0 ເພື່ອ log query ທັງໝົດ, ແລ້ວກວດສອບວ່າມີ query ທີ່ມີຮູບແບບດຽວກັນຕໍ່ເນື່ອງກັນຫຼືບໍ່. ສຳລັບ Rails ມີ bullet gem, ສຳລັບ Django ມີ django-debug-toolbar ເປັນເຄື່ອງມືກວດຫາ.
ພຽງແຕ່ໃສ່ໃຈໃນຂັ້ນຕອນ code review ວ່າ "ມີ await ຢູ່ພາຍໃນ loop ຫຼືບໍ່", ກໍສາມາດປ້ອງກັນ N+1 ໄດ້ຫຼາຍກໍລະນີ.



ວິທີການອອກແບບທີ່ກຳຈັດຄວາມສ່ຽງຂອງການຮົ່ວໄຫຼຂໍ້ມູນສ່ວນຕົວຢ່າງເປັນໂຄງສ້າງ ໂດຍການແຍກລະບົບ AI ແລະໂຄງສ້າງພື້ນຖານການປະມວນຜົນຂໍ້ມູນອອກຈາກກັນທາງດ້ານກາຍຍະພາບ ແລະທາງດ້ານຕາມເຫດຜົນ (Logical). ຕົວຢ່າງທີ່ເປັນຕົວແທນຂອງວິທີນີ້ ໄດ້ແກ່ການແຍກ Tenant ແລະການດຳເນີນງານແບບ On-premises.

ຖານຂໍ້ມູນເວັກເຕີ (Vector Database) ແມ່ນຖານຂໍ້ມູນທີ່ເກັບຮັກສາຂໍ້ຄວາມ ແລະ ຮູບພາບເປັນເວັກເຕີຕົວເລກ (Embedding) ແລະ ໃຫ້ບໍລິການຄົ້ນຫາໄວຕາມຄວາມຄ້າຍຄືກັນທາງຄວາມໝາຍ.

Zero Trust Network Access (ZTNA) ແມ່ນຮູບແບບຄວາມປອດໄພທີ່ຄວບຄຸມການເຂົ້າເຖິງຊັບພະຍາກອນເຄືອຂ່າຍ ໂດຍອີງໃສ່ຫຼັກການ "ບໍ່ໄວ້ວາງໃຈໃຜ ແລະ ກວດສອບສະເໝີ" ດ້ວຍການກວດສອບຜູ້ໃຊ້ ແລະ ອຸປະກອນຢ່າງຕໍ່ເນື່ອງ.