มันจะมีประสิทธิภาพมากขึ้นในการจัดเก็บค่าของคุณในสคีมาปกติ ที่กล่าวว่าคุณยังสามารถใช้งานได้กับการตั้งค่าปัจจุบันของคุณ
สมมติฐาน
สมมติว่านิยามตารางนี้:
CREATE TABLE tbl (tbl_id int, usr jsonb);
"ผู้ใช้" เป็นคำที่สงวนไว้และจะต้องใช้การอ้างอิงสองครั้งเพื่อใช้เป็นชื่อคอลัมน์ อย่าทำอย่างนั้น ฉันใช้usr
แทน
สอบถาม
ข้อความค้นหานั้นไม่สำคัญเท่ากับความคิดเห็น (ลบแล้ว) ทำให้ดูเหมือนว่า:
SELECT t.tbl_id, obj.val->>'count' AS count
FROM tbl t
JOIN LATERAL jsonb_array_elements(t.usr) obj(val) ON obj.val->>'_id' = '1'
WHERE t.usr @> '[{"_id":"1"}]';
มี3 ขั้นตอนพื้นฐาน :
1. ระบุแถวที่มีคุณสมบัติเหมาะสมในราคาถูก
WHERE t.usr @> '[{"_id":"1"}]'
ระบุแถวที่มีวัตถุที่ตรงกันในอาร์เรย์ JSON นิพจน์สามารถใช้ดัชนี GIN ทั่วไปในjsonb
คอลัมน์หรือหนึ่งรายการที่มีคลาสโอเปอเรเตอร์ที่เฉพาะเจาะจงมากขึ้นjsonb_path_ops
:
CREATE INDEX tbl_usr_gin_idx ON tbl USING gin (usr jsonb_path_ops);
WHERE
อนุประโยคที่เพิ่มเข้ามานั้นซ้ำซ้อนในเชิงตรรกะแต่จำเป็นต้องใช้ดัชนี การแสดงออกในการเข้าร่วมข้อบังคับเงื่อนไขเดียวกัน แต่หลังจากการยกเลิกอาร์เรย์ในทุกแถวที่มีคุณสมบัติจนถึงตอนนี้ ด้วยการสนับสนุนดัชนี Postgres จะประมวลผลแถวที่มีวัตถุที่มีคุณสมบัติตามที่กำหนดเพื่อเริ่มต้นเท่านั้น ไม่สำคัญกับโต๊ะเล็ก ๆ แต่สร้างความแตกต่างอย่างมากกับโต๊ะใหญ่และแถวที่มีคุณสมบัติเพียงไม่กี่แถว
ที่เกี่ยวข้อง:
2. ระบุวัตถุที่ตรงกันในอาเรย์
Unnest jsonb_array_elements()
กับ ( unnest()
เหมาะสำหรับประเภทอาร์เรย์ Postgres เท่านั้น) เนื่องจากเราสนใจเฉพาะวัตถุที่ตรงกันเท่านั้นจึงกรองในเงื่อนไขการเข้าร่วมได้ทันที
ที่เกี่ยวข้อง:
3. แยกค่าสำหรับคีย์ที่ซ้อนกัน 'count'
หลังจากแยกวัตถุที่ผ่านการคัดเลือกแล้วเพียง: obj.val->>'count'
.
obj(value)
มาจากไหน? มันอยู่ในLATERAL JOIN
ที่jsonb_array_elements
หรือที่อื่น?