2011-09-23 31 views
10

Các tài liệu cho Pg's Window function say:Postgres sẽ đẩy mệnh đề WHERE vào VIEW với chức năng Window (Tổng hợp)?

Các hàng xem xét một hàm cửa sổ là của các "bảng ảo" được tạo ra bởi các truy vấn mệnh đề FROM như lọc bởi khoản WHERE, GROUP BY và HAVING của mình nếu có. Ví dụ, một hàng bị xóa vì nó không đáp ứng điều kiện WHERE không được nhìn thấy bởi bất kỳ chức năng cửa sổ nào. Truy vấn có thể chứa nhiều chức năng cửa sổ chia nhỏ dữ liệu theo nhiều cách khác nhau bằng các mệnh đề OVER khác nhau, nhưng tất cả đều hoạt động trên cùng một tập hợp các hàng được xác định bởi bảng ảo này.

Tuy nhiên, tôi không thấy điều này. Dường như với tôi như Select Filter là rất gần với lề trái và trên cùng (điều cuối cùng được thực hiện).

=# EXPLAIN SELECT * FROM chrome_nvd.view_options where fkey_style = 303451; 
                 QUERY PLAN              
---------------------------------------------------------------------------------------------------------------------- 
Subquery Scan view_options (cost=2098450.26..2142926.28 rows=14825 width=180) 
    Filter: (view_options.fkey_style = 303451) 
    -> Sort (cost=2098450.26..2105862.93 rows=2965068 width=189) 
     Sort Key: o.sequence 
     -> WindowAgg (cost=1446776.02..1506077.38 rows=2965068 width=189) 
       -> Sort (cost=1446776.02..1454188.69 rows=2965068 width=189) 
        Sort Key: h.name, k.name 
        -> WindowAgg (cost=802514.45..854403.14 rows=2965068 width=189) 
          -> Sort (cost=802514.45..809927.12 rows=2965068 width=189) 
           Sort Key: h.name 
           -> Hash Join (cost=18.52..210141.57 rows=2965068 width=189) 
             Hash Cond: (o.fkey_opt_header = h.id) 
             -> Hash Join (cost=3.72..169357.09 rows=2965068 width=166) 
              Hash Cond: (o.fkey_opt_kind = k.id) 
              -> Seq Scan on options o (cost=0.00..128583.68 rows=2965068 width=156) 
              -> Hash (cost=2.21..2.21 rows=121 width=18) 
                -> Seq Scan on opt_kind k (cost=0.00..2.21 rows=121 width=18) 
             -> Hash (cost=8.80..8.80 rows=480 width=31) 
              -> Seq Scan on opt_header h (cost=0.00..8.80 rows=480 width=31) 
(19 rows) 

Hai WindowAgg của bản chất thay đổi kế hoạch để một cái gì đó mà dường như không bao giờ kết thúc từ nhanh hơn nhiều

                 QUERY PLAN                  
-------------------------------------------------------------------------------------------------------------------------------------------------------- 
Subquery Scan view_options (cost=329.47..330.42 rows=76 width=164) (actual time=20.263..20.403 rows=42 loops=1) 
    -> Sort (cost=329.47..329.66 rows=76 width=189) (actual time=20.258..20.300 rows=42 loops=1) 
     Sort Key: o.sequence 
     Sort Method: quicksort Memory: 35kB 
     -> Hash Join (cost=18.52..327.10 rows=76 width=189) (actual time=19.427..19.961 rows=42 loops=1) 
       Hash Cond: (o.fkey_opt_header = h.id) 
       -> Hash Join (cost=3.72..311.25 rows=76 width=166) (actual time=17.679..18.085 rows=42 loops=1) 
        Hash Cond: (o.fkey_opt_kind = k.id) 
        -> Index Scan using options_pkey on options o (cost=0.00..306.48 rows=76 width=156) (actual time=17.152..17.410 rows=42 loops=1) 
          Index Cond: (fkey_style = 303451) 
        -> Hash (cost=2.21..2.21 rows=121 width=18) (actual time=0.432..0.432 rows=121 loops=1) 
          -> Seq Scan on opt_kind k (cost=0.00..2.21 rows=121 width=18) (actual time=0.042..0.196 rows=121 loops=1) 
       -> Hash (cost=8.80..8.80 rows=480 width=31) (actual time=1.687..1.687 rows=480 loops=1) 
        -> Seq Scan on opt_header h (cost=0.00..8.80 rows=480 width=31) (actual time=0.030..0.748 rows=480 loops=1) 
Total runtime: 20.893 ms 
(15 rows) 

gì đang xảy ra, và làm thế nào để sửa chữa nó? Tôi đang sử dụng Postgresql 8.4.8. Dưới đây là những gì chế độ xem thực tế đang thực hiện:

SELECT o.fkey_style, h.name AS header, k.name AS kind 
    , o.code, o.name AS option_name, o.description 
    , count(*) OVER (PARTITION BY h.name) AS header_count 
    , count(*) OVER (PARTITION BY h.name, k.name) AS header_kind_count 
    FROM chrome_nvd.options o 
    JOIN chrome_nvd.opt_header h ON h.id = o.fkey_opt_header 
    JOIN chrome_nvd.opt_kind k ON k.id = o.fkey_opt_kind 
    ORDER BY o.sequence; 
+1

Xin lỗi, tôi không thấy một chức năng WINDOW trong truy vấn của bạn. Có VIEW nào liên quan không? Vui lòng thêm các định nghĩa bảng/chế độ xem/chỉ mục có liên quan. – wildplasser

+0

Có, tôi đã dán nội dung xem ngay bây giờ. –

+1

Đó thực sự là những gì đang xảy ra. Postgres không truyền mệnh đề 'WHERE' bên trong khung nhìn, trước khi thực hiện chức năng cửa sổ. Hấp dẫn. –

Trả lời

3

Không, PostgreSQL sẽ chỉ đẩy mệnh đề WHERE trên VIEW không có Tổng hợp. (Các chức năng cửa sổ được xem xét là Tổng hợp).

< x> Tôi nghĩ rằng đó chỉ là một giới hạn thực hiện

< EvanCarroll> x: Tôi tự hỏi điều gì sẽ phải được thực hiện để đẩy mệnh đề WHERE xuống trong trường hợp này.

< EvanCarroll> người lập kế hoạch phải biết rằng WindowAgg không tự thêm tính chọn lọc và do đó an toàn khi đẩy WHERE xuống?

< x> EvanCarroll; rất nhiều công việc rất phức tạp với các nhà quy hoạch, tôi đoán

Và,

< a> EvanCarroll: nope. một điều kiện lọc trên một cái nhìn áp dụng cho đầu ra về quan điểm và chỉ được đẩy xuống nếu quan điểm không liên quan đến uẩn

+0

.. có ý nghĩa, bởi vì nó có thể thay đổi kết quả. Điều này giống như sự khác biệt giữa 'WHERE' và' HAVING'. –

+0

Phải, nhưng trong trường hợp này nó sẽ không.Nó cũng có vẻ như tôi như một chức năng cửa sổ là một chút căng. Tôi không thể nghĩ về một chức năng Window không tham chiếu có thể thay đổi kết quả nếu WHERE bị đẩy xuống. –

+0

Hình như có tiềm năng cho một số tối ưu hóa thông minh. Trong thời gian chờ đợi, bạn sẽ phải tự mình giảm mệnh đề WHERE. Nếu bạn cần một hình thức tổng quát, bạn có thể sử dụng các thủ tục được lưu trữ. Bạn có cần một ví dụ? –

Các vấn đề liên quan