ฉันใช้ postgres 9.4
The messages
มีสคีมาดังต่อไปนี้: ข้อความเป็นของ feed_id และโพสต์ _at และข้อความสามารถมีข้อความหลัก (ในกรณีที่ตอบกลับ)
Table "public.messages"
Column | Type | Modifiers
------------------------------+-----------------------------+-----------
message_id | character varying(255) | not null
feed_id | integer |
parent_id | character varying(255) |
posted_at | timestamp without time zone |
share_count | integer |
Indexes:
"messages_pkey" PRIMARY KEY, btree (message_id)
"index_messages_on_feed_id_posted_at" btree (feed_id, posted_at DESC NULLS LAST)
ฉันต้องการส่งคืนข้อความทั้งหมดที่สั่งซื้อโดยshare_count
แต่สำหรับแต่ละข้อความparent_id
ฉันต้องการส่งคืนข้อความเดียวเท่านั้น กล่าวคือหากข้อความหลายข้อความมีข้อความเหมือนกันระบบจะส่งกลับparent_id
เฉพาะข้อความล่าสุด ( posted_at
) เท่านั้น parent_id
สามารถเป็นโมฆะข้อความที่มี null parent_id
ควรทั้งหมดกลับมา
แบบสอบถามที่ฉันใช้คือ:
WITH filtered_messages AS (SELECT *
FROM messages
WHERE feed_id IN (7)
AND (posted_at >= '2015-01-01 04:00:00.000000')
AND (posted_at < '2015-04-28 04:00:00.000000'))
SELECT *
FROM (SELECT DISTINCT ON(COALESCE(parent_id, message_id)) parent_id,
message_id,
posted_at,
share_count
FROM filtered_messages
ORDER BY COALESCE(parent_id, message_id), posted_at DESC NULLS LAST
) messages
ORDER BY share_count DESC NULLS LAST, posted_at DESC NULLS LAST;
นี่คือhttp://sqlfiddle.com/#!15/588e5/1/0ใน SQL Fiddle ฉันได้กำหนดสคีมาแบบสอบถามที่แน่นอนและผลลัพธ์ที่คาดหวัง
แต่ประสิทธิภาพของแบบสอบถามช้าเมื่อตารางข้อความมีขนาดใหญ่ ฉันพยายามเพิ่มดัชนีการเรียงลำดับหลายรายการ แต่ดูเหมือนจะไม่ใช้ดัชนี นี่คือคำอธิบาย: http://explain.depesz.com/s/Sv2
ฉันจะสร้างดัชนีที่ถูกต้องได้อย่างไร
feed_id
และposted_at
คุณไม่ได้พูดถึงmetadata
เลยซึ่งดูเหมือนจะเป็นประเภท JSON? โปรดซ่อมแซมคำถามของคุณเพื่อให้สอดคล้องกัน คุณเลือก> 500k rows ใน CTE ... มีกี่แถวในตาราง? เปอร์เซ็นต์ของแถวที่คุณเลือกใน CTE เปอร์เซ็นต์ของแถวมีparent_id IS NULL
อะไรบ้าง พิจารณาข้อมูลในแท็ก[postgresql-performance]สำหรับคำถามเกี่ยวกับประสิทธิภาพ
parent_id
? (นาที / เฉลี่ย / สูงสุด)
metadata
hstore ขณะนี้ตารางข้อความมีข้อมูล 10 ล้าน แต่เพิ่มขึ้นอย่างรวดเร็ว ฉันคิดว่าจะแยกเป็นตารางพาร์ติชันสำหรับแต่ละ feed_id เนื่องจากฉันดึงข้อมูลตามรหัสฟีดเท่านั้น เปอร์เซ็นต์ของ parent_id null และไม่เป็นโมฆะคือประมาณ 60% / 40% การดึงข้อมูลทั่วไปอยู่ที่ประมาณ 1-2% ของตาราง (ประมาณข้อความ 100K) ประสิทธิภาพสำหรับ 100K อยู่ที่ประมาณ 1s แต่เมื่อถึง 500K + จะใช้ดัชนีบิตแมปและใช้เวลาปกติ 10 วินาที
ORDER BY
ในแบบสอบถามย่อยจะไร้ประโยชน์โดยสิ้นเชิง นอกจากนี้แผนเชื่อมโยงไม่สามารถเป็นผลมาจากแบบสอบถามที่โพสต์ - ไม่มีการกล่าวถึงmetadata
เช่น