Nói chung, công cụ lập kế hoạch truy vấn Postgres hiện chế độ xem "nội tuyến" để tối ưu hóa toàn bộ truy vấn. Theo tài liệu:
Nhưng tôi không nghĩ Postgres đủ thông minh để kết luận rằng nó có thể đạt được cùng một kết quả từ bảng cơ sở mà không làm bùng nổ các hàng.
Bạn có thể thử truy vấn thay thế này bằng LATERAL
tham gia. Nó sạch hơn:
CREATE OR REPLACE VIEW runinfo.v_mt_count_by_day AS
SELECT m.run_id, m.type, m.brand
, m.start_day + c.rn - 1 AS row_date
, c.row_count
FROM runinfo.mt_count_by_day m
LEFT JOIN LATERAL unnest(m.counts) WITH ORDINALITY c(row_count, rn) ON true;
Nó cũng làm rõ rằng một trong (end_day
, start_day
) là thừa.
Sử dụng LEFT JOIN
bởi vì điều đó có thể cho phép người lập kế hoạch truy vấn bỏ qua kết hợp khỏi truy vấn của bạn:
SELECT DISTINCT type FROM v_mt_count_by_day;
Khác (với CROSS JOIN
hoặc INNER JOIN
) nó phải đánh giá kết hợp để xem liệu các hàng từ bảng đầu tiên có bị loại bỏ hay không.
BTW, đó là:
SELECT DISTINCT type ...
không phải:
SELECT DISTINCT(type) ...
Lưu ý rằng điều này trả về một date
thay vì dấu thời gian trong bản gốc của bạn. Dễ dàng hơn, và tôi đoán đó là những gì bạn muốn?
Yêu cầu Postgres 9.3+ Chi tiết:
ROWS FROM
trong Postgres 9.4+
Để phát nổ song song cả hai cột một cách an toàn :
CREATE OR REPLACE VIEW runinfo.v_mt_count_by_day AS
SELECT m.run_id, m.type, m.brand
t.row_date::date, t.row_count
FROM runinfo.mt_count_by_day m
LEFT JOIN LATERAL ROWS FROM (
unnest(m.counts)
, generate_series(m.start_day, m.end_day, interval '1d')
) t(row_count, row_date) ON true;
Lợi ích chính:Điều này sẽ không bị trật bánh thành một sản phẩm Descartes nếu hai SRF không trả về cùng một số hàng. Thay vào đó, giá trị NULL sẽ được đệm.
Một lần nữa, tôi không thể nói liệu điều này có giúp người lập kế hoạch truy vấn lập kế hoạch nhanh hơn cho DISTINCT type
hay không mà không cần thử nghiệm.