คุณอาจไม่อยากได้ยินสิ่งนี้ แต่ทางเลือกที่ดีที่สุดในการเร่งความเร็วSELECT DISTINCT
คือการหลีกเลี่ยง DISTINCT
การเริ่มต้น ในหลายกรณี (ไม่ใช่ทั้งหมด!) สามารถหลีกเลี่ยงได้ด้วยการออกแบบฐานข้อมูลหรือแบบสอบถามที่ดีขึ้น
บางครั้งGROUP BY
เร็วกว่าเพราะใช้เส้นทางรหัสที่แตกต่าง
ในกรณีเฉพาะของคุณดูเหมือนจะไม่สามารถกำจัดDISTINCT
ได้ แต่คุณสามารถรองรับการสืบค้นด้วยดัชนีเฉพาะถ้าคุณมีการสืบค้นหลายประเภท:
CREATE INDEX foo ON events (project_id, "time", user_id);
การเพิ่มuser_id
จะมีประโยชน์ก็ต่อเมื่อคุณสแกนเฉพาะดัชนีนี้เท่านั้น ไปที่ลิงก์เพื่อดูรายละเอียด จะลบBitmap Heap Scanราคาแพงออกจากแผนคิวรีของคุณซึ่งใช้ 90% ของเวลาแบบสอบถาม
EXPLAIN
ผลลัพธ์ของคุณบอกฉันว่าข้อความค้นหาต้องย่อผู้ใช้ 2,491 รายออกจากแถวที่ตรงกันครึ่งล้าน สิ่งนี้จะไม่เร็วอย่างมากไม่ว่าคุณจะทำอะไร แต่ก็สามารถเร็วขึ้นอย่างมาก
หากช่วงเวลาในแบบสอบถามของคุณเหมือนกันเสมอการMATERIALIIZED VIEW
พับuser_id
แต่ละครั้ง(project_id, <fixed time intervall>)
จะไปไกล ไม่มีโอกาสที่จะมีช่วงเวลาที่แตกต่างกัน บางทีคุณอาจพับผู้ใช้อย่างน้อยต่อชั่วโมงหรือบางหน่วยเวลาขั้นต่ำอื่น ๆ และนั่นจะซื้อประสิทธิภาพเพียงพอที่จะรับประกันค่าใช้จ่ายจำนวนมาก
Nitpick:
ส่วนใหญ่เพรดิเคตที่"time"
ควรจะเป็น:
AND "time" >= '2015-01-11 8:00:00'
AND "time" < '2015-02-10 8:00:00';
นอกเหนือ:
อย่าใช้time
เป็นตัวระบุ มันเป็นคำสงวนใน SQL มาตรฐานและเป็นประเภทพื้นฐานใน Postgres