Có cách nào để tôi buộc phải tham gia một đơn đặt hàng cụ thể trong Postgres không?Thứ tự tham gia bảng trong bưu điện
Tôi có một truy vấn giống như thế này. Tôi đã loại bỏ một loạt các nội dung trong truy vấn thực sự, nhưng sự đơn giản hóa này cho thấy sự cố. Những gì còn lại không nên quá khó hiểu: Sử dụng một vai trò/nhiệm vụ bảo mật hệ thống, tôi đang cố gắng để xác định xem một người dùng nhất định có đặc quyền để thực hiện một nhiệm vụ nhất định.
select task.taskid
from userlogin
join userrole using (userloginid)
join roletask using (roleid)
join task using (taskid)
where loginname='foobar'
and taskfunction='plugh'
Nhưng tôi nhận ra rằng chương trình đã biết giá trị của UserLogin, vì vậy nó có vẻ các truy vấn có thể được thực hiện hiệu quả hơn bằng cách bỏ qua việc tra cứu trên UserLogin và chỉ cần điền vào userloginid, như thế này:
select task.taskid
from userrole
join roletask using (roleid)
join task using (taskid)
where userloginid=42
and taskfunction='plugh'
Khi tôi làm điều đó - loại bỏ một bảng khỏi truy vấn và mã hóa cứng giá trị được truy xuất từ bảng đó thay thế - thời gian lập kế hoạch giải thích tăng lên! Trong truy vấn ban đầu, Postgres đọc userlogin sau đó userrole sau đó roletask sau đó nhiệm vụ. Nhưng trong truy vấn mới, nó quyết định đọc roletask đầu tiên, và sau đó tham gia vào userrole, mặc dù điều này yêu cầu thực hiện quét toàn bộ tệp trên roletask.
Full giải thích kế hoạch là:
Phiên bản 1:
Hash Join (cost=12.79..140.82 rows=1 width=8)
Hash Cond: (roletask.taskid = task.taskid)
-> Nested Loop (cost=4.51..129.73 rows=748 width=8)
-> Nested Loop (cost=4.51..101.09 rows=12 width=8)
-> Index Scan using idx_userlogin_loginname on userlogin (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((loginname)::text = 'foobar'::text)
-> Bitmap Heap Scan on userrole (cost=4.51..92.41 rows=33 width=16)
Recheck Cond: (userrole.userloginid = userlogin.userloginid)
-> Bitmap Index Scan on idx_userrole_login (cost=0.00..4.50 rows=33 width=0)
Index Cond: (userrole.userloginid = userlogin.userloginid)
-> Index Scan using idx_roletask_role on roletask (cost=0.00..1.50 rows=71 width=16)
Index Cond: (roletask.roleid = userrole.roleid)
-> Hash (cost=8.27..8.27 rows=1 width=8)
-> Index Scan using idx_task_taskfunction on task (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((taskfunction)::text = 'plugh'::text)
Version 2:
Hash Join (cost=96.58..192.82 rows=4 width=8)
Hash Cond: (roletask.roleid = userrole.roleid)
-> Hash Join (cost=8.28..104.10 rows=9 width=16)
Hash Cond: (roletask.taskid = task.taskid)
-> Seq Scan on roletask (cost=0.00..78.35 rows=4635 width=16)
-> Hash (cost=8.27..8.27 rows=1 width=8)
-> Index Scan using idx_task_taskfunction on task (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((taskfunction)::text = 'plugh'::text)
-> Hash (cost=87.92..87.92 rows=31 width=8)
-> Bitmap Heap Scan on userrole (cost=4.49..87.92 rows=31 width=8)
Recheck Cond: (userloginid = 42)
-> Bitmap Index Scan on idx_userrole_login (cost=0.00..4.49 rows=31 width=0)
Index Cond: (userloginid = 42)
(Vâng, tôi biết rằng trong cả hai trường hợp, chi phí thấp và sự khác biệt doesn Nhưng đây là sau khi tôi loại bỏ một loạt các công việc bổ sung từ truy vấn để đơn giản hóa những gì tôi phải đăng. Truy vấn thực sự vẫn không phải là thái quá, nhưng tôi quan tâm nhiều hơn đến t . Ông nguyên tắc)
Bạn có thể hiển thị kế hoạch truy vấn (giải thích phân tích) và định nghĩa bảng không? – hgmnz
Được rồi, bạn đã hỏi, tôi đã thay thế ví dụ đơn giản giả định bằng truy vấn thực và thêm kết quả kế hoạch giải thích. Ồ, tôi chắc chắn rằng tôi có thể thêm một số chỉ mục bổ sung để tăng tốc truy vấn thứ hai, nhưng đó không phải là vấn đề. Tại sao Postgres lại chọn một kế hoạch ít hơn mức tốt nhất mà nó có thể làm, với các truy vấn mà nó có? Đặc biệt là khi nó chứng minh rằng nó có thể làm tốt hơn nếu tôi làm cho truy vấn phức tạp hơn? – Jay
bạn có so sánh thời gian chạy thực tế của các truy vấn hoặc chỉ xem chi phí tiêu đề trong kế hoạch giải thích không? chi phí? đáng chú ý là bạn vừa đăng đầu ra giải thích, chứ không giải thích phân tích. mặc dù bạn mong đợi chi phí cao hơn để tương đương với một truy vấn chạy chậm hơn, nó có thể không hoạt động theo cách đó. – araqnid