ฟังก์ชัน PL / PgSQL และ SQL ธรรมดาเป็นส่วนหนึ่งของชุดเครื่องมือที่ใหญ่ขึ้นและควรดูในบริบทนั้น ฉันมักจะคิดในแง่ของระดับพลังงานที่สูงขึ้นซึ่งจับคู่โดยความซับซ้อนและต้นทุนที่สูงขึ้นซึ่งคุณควรใช้เครื่องมือที่ง่ายที่สุดที่จะทำงานได้ดี:
- ใช้มุมมองที่เป็นไปได้
- ในกรณีที่มุมมองไม่เหมาะสมให้ใช้ฟังก์ชัน SQL
- ในกรณีที่ฟังก์ชัน SQL ไม่เหมาะสมให้ใช้ PL / PgSQL
- ในกรณีที่ PL / PgSQL มีข้อ จำกัด หรือไม่ชัดเจนเพียงพอให้ใช้ PL / Perl, PL / Python, PL / V8, PL / Java หรืออะไรก็ตามที่คุณต้องการ
- ... และที่ใดที่ PL จะไม่ทำงานให้ใช้โปรแกรมภายนอกและอาจ
LISTEN
และNOTIFY
เพื่อพูดคุยกับมัน
บ่อยครั้งที่มุมมองนั้นเพียงพอเมื่อคุณคิดว่าจำเป็นต้องใช้ฟังก์ชั่น แม้ว่าจะมีราคาแพงมากสำหรับSELECT
มุมมองทั้งหมด แต่WHERE
คำสั่งย่อยในแบบสอบถามที่อ้างอิงมุมมองนั้นมักจะถูกผลักลงไปในมุมมองและอาจส่งผลให้เกิดแผนแบบสอบถามที่แตกต่างกันมาก ฉันมักจะมีการปรับปรุงประสิทธิภาพขนาดใหญ่จากการแปลงฟังก์ชัน SQL เป็นมุมมอง
เวลาหลักที่คุณพบว่าคุณไม่สามารถใช้มุมมองและควรพิจารณาฟังก์ชัน SQL คือเมื่อ:
- พารามิเตอร์ที่ไม่สามารถแสดงว่าเป็น
WHERE
คำสั่งแบบง่ายได้เช่นพารามิเตอร์ภายในWITH
นิพจน์
- คุณต้องการอุปสรรคด้านความปลอดภัยผ่าน
SECURITY DEFINER
ฟังก์ชั่นและsecurity_barrier
มุมมองใน PostgreSQL 9.2 ขึ้นไปนั้นไม่เพียงพอสำหรับความต้องการของคุณ
- คุณต้องการพารามิเตอร์ที่ไม่ถูกส่งลงในส่วนย่อยของมุมมองโดยโปรแกรมเพิ่มประสิทธิภาพและต้องการควบคุมโดยตรงมากกว่า หรือ
- มี params จำนวนมากหรือมีการทำซ้ำของ params มากมายดังนั้นจึงไม่สามารถเขียนแบบสอบถามเป็นมุมมองได้
สำหรับงานเหล่านั้นส่วนใหญ่ฟังก์ชั่น SQL ธรรมดาทำงานได้ดีและมักจะอ่านง่ายกว่า PL / PgSQL ฟังก์ชั่น SQL ที่ประกาศSTABLE
หรือIMMUTABLE
(และยังไม่ประกาศSTRICT
หรือSECURITY DEFINER
) ยังสามารถ inline ลงในคำสั่งการโทร ที่ได้รับการกำจัดของค่าใช้จ่ายการเรียกใช้ฟังก์ชั่นและบางครั้งก็อาจส่งผลให้เกิดประโยชน์อย่างมากเมื่อเงื่อนไข WHERE ในฟังก์ชั่นการโทรได้รับการผลักลงในฟังก์ชั่น SQL โดยเพิ่มประสิทธิภาพ ใช้ฟังก์ชัน SQL เมื่อใดก็ตามที่เพียงพอสำหรับงาน
ฟังก์ชัน SQL เวลาหลักจะไม่ทำงานเมื่อคุณต้องการตรรกะจำนวนมาก หากการดำเนินการ / then / else ที่คุณไม่สามารถแสดงเป็นCASE
คำสั่งได้นั้นจะใช้ผลการคำนวณจำนวนมากอีกครั้งการสร้างมูลค่าจากชิ้นส่วนการจัดการข้อผิดพลาด ฯลฯ PL / PgSQL มีประโยชน์อย่างมาก เลือก PL / PgSQL เมื่อคุณไม่สามารถใช้ฟังก์ชั่น SQL ไม่เช่นนั้น:
- Dynamic SQL และ DDL แบบไดนามิกผ่าน
EXECUTE
คำสั่ง
- เมื่อคุณต้องการ
RAISE
ข้อผิดพลาด / คำเตือนสำหรับบันทึกหรือลูกค้า
- เมื่อคุณต้องการจัดการข้อยกเว้น - คุณสามารถดักจับและจัดการข้อผิดพลาดด้วย
EXCEPTION
บล็อกแทนการทำธุรกรรมทั้งหมดยุติข้อผิดพลาด
- ตรรกะเงื่อนไขที่ซับซ้อนที่ไม่เหมาะสม
CASE ... WHEN
เป็นอย่างดี
- มีการใช้ค่าที่คำนวณได้จำนวนมากซึ่งคุณไม่สามารถนำไปใช้กับ
WITH
CTE ได้
- การสร้างบันทึกแบบไดนามิก
- คุณต้องดำเนินการหลังจากสร้างชุดผลลัพธ์
ด้วยตารางนิพจน์ทั่วไป (CTE) โดยเฉพาะอย่างยิ่ง CTE ที่เขียนได้และWITH RECURSIVE
ฉันพบว่าฉันใช้ PL / PgSQL น้อยกว่าที่ฉันเคยใช้เพราะ SQL นั้นแสดงออกและทรงพลังกว่ามาก ฉันใช้มุมมองและฟังก์ชั่น SQL ธรรมดามากขึ้นตอนนี้ มันควรค่าแก่การจดจำว่าฟังก์ชัน SQL ธรรมดาสามารถมีมากกว่าหนึ่งคำสั่ง; คำสั่งสุดท้ายคือผลลัพธ์ของฟังก์ชัน