Tôi gặp rắc rối với kế hoạch truy vấn PostgreSQL 9.6. Truy vấn của tôi trông như thế này:
SET role plain_user;
SELECT properties.*
FROM properties
JOIN entries_properties
ON properties.id = entries_properties.property_id
JOIN structures
ON structures.id = entries_properties.entry_id
WHERE structures."STRUKTURBERICHT" != ''
AND properties."COMPOSITION" LIKE 'Mo%'
AND (
properties."NAME" LIKE '%VASP-ase-preopt%'
OR properties."CALCULATOR_ID" IN (7,22,25)
)
AND properties."TYPE_ID" IN (6)
Tôi đã bật Bảo mật cấp hàng cho các bảng được sử dụng ở trên.
với
set enable_nestloop = True
, trình lập kế hoạch truy vấn chạy kết nối Nested Loop với tổng thời gian chạy khoảng 37 giây: https://explain.depesz.com/s/59BRvới
set enable_nestloop = False
, phương thức Hash Join được sử dụng và thời gian truy vấn khoảng 0,3 giây: https://explain.depesz.com/s/PG8E
Tôi đã làm VACUUM ANALYZE
trước khi chạy các truy vấn, nhưng nó không giúp được gì.
Tôi biết rằng nó không phải là một thực hành tốt set enable_nestloop = False
, và bất kỳ tùy chọn tương tự khác cho người lập kế hoạch. Nhưng làm thế nào tôi có thể "thuyết phục" người lập kế hoạch sử dụng phép nối băm mà không vô hiệu hóa các vòng lặp lồng nhau?
Viết lại truy vấn là một tùy chọn.
Nếu tôi chạy cùng một truy vấn theo vai trò bỏ qua RLS, thì nó được thực thi rất nhanh. Chính sách bảo mật cấp hàng trông như thế này:
CREATE POLICY properties_select
ON properties
FOR SELECT
USING (
(
properties.ouid = get_current_user_id()
AND properties.ur
)
OR (
properties.ogid in (select get_current_groups_id())
AND properties.gr
)
OR properties.ar
);
Bất kỳ ý tưởng hoặc đề xuất sẽ được đánh giá cao.
AND properties."TYPE_ID" IN (6);
và không= 6;
?