hiệu suất postgres_fdw chậm


12

Truy vấn sau đây đối với người nước ngoài mất khoảng 5 giây để thực hiện trên 3,2 triệu hàng:

SELECT x."IncidentTypeCode", COUNT(x."IncidentTypeCode") 
FROM "IntterraNearRealTimeUnitReflexes300sForeign" x 
WHERE x."IncidentDateTime" >= '05/01/2016' 
GROUP BY x."IncidentTypeCode" 
ORDER BY 1;

Khi tôi thực hiện cùng một truy vấn trên bảng bình thường, nó sẽ trả về .6 giây. Các kế hoạch thực hiện khá khác nhau:

Bảng bình thường

Sort  (cost=226861.20..226861.21 rows=4 width=4) (actual time=646.447..646.448 rows=7 loops=1) 
  Sort Key: "IncidentTypeCode" 
  Sort Method: quicksort  Memory: 25kB 
  -> HashAggregate (cost=226861.12..226861.16 rows=4 width=4) (actual  time=646.433..646.434 rows=7 loops=1)
     Group Key: "IncidentTypeCode"
     -> Bitmap Heap Scan on "IntterraNearRealTimeUnitReflexes300s" x  (cost=10597.63..223318.41 rows=708542 width=4) (actual time=74.593..342.110 rows=709376 loops=1) 
        Recheck Cond: ("IncidentDateTime" >= '2016-05-01 00:00:00'::timestamp without time zone) 
        Rows Removed by Index Recheck: 12259 
        Heap Blocks: exact=27052 lossy=26888
        -> Bitmap Index Scan on idx_incident_date_time_300  (cost=0.00..10420.49 rows=708542 width=0) (actual time=69.722..69.722 rows=709376 loops=1) 
           Index Cond: ("IncidentDateTime" >= '2016-05-01 00:00:00'::timestamp without time zone) 

Planning time: 0.165 ms 
Execution time: 646.512 ms

Bảng ngoại

Sort  (cost=241132.04..241132.05 rows=4 width=4) (actual time=4782.110..4782.112 rows=7 loops=1)   
  Sort Key: "IncidentTypeCode" 
  Sort Method: quicksort  Memory: 25kB
  -> HashAggregate  (cost=241131.96..241132.00 rows=4 width=4) (actual time=4782.097..4782.100 rows=7 loops=1)
     Group Key: "IncidentTypeCode"
     -> Foreign Scan on "IntterraNearRealTimeUnitReflexes300sForeign" x  (cost=10697.63..237589.25 rows=708542 width=4) (actual time=1.916..4476.946 rows=709376 loops=1) 

Planning time: 1.413 ms 
Execution time: 4782.660 ms

Tôi nghĩ rằng tôi đang trả giá cao cho GROUP BYđiều khoản, điều này không được chuyển đến máy chủ nước ngoài khi tôi EXPLAIN VERBOSE:

SELECT
    "IncidentTypeCode"
FROM
    PUBLIC ."IntterraNearRealTimeUnitReflexes300s"
WHERE
    (
        (
            "IncidentDateTime" >= '2016-05-01 00:00:00' :: TIMESTAMP WITHOUT TIME ZONE
        )
    )

Điều này trả về 700k hàng. Có cách nào để giái quyết vấn đề này không?

Tôi đã dành rất nhiều thời gian để đọc trang tài liệu này ngày hôm qua, và nghĩ rằng tôi đã tìm thấy câu trả lời của mình với cài đặt use_remote_estimatethành đúng, nhưng nó không có tác dụng.

Tôi có quyền truy cập vào máy chủ nước ngoài để tạo đối tượng nếu cần thiết. Giá trị dấu thời gian trong WHEREmệnh đề có thể là bất cứ điều gì; nó không đến từ một danh sách các giá trị được xác định trước.


3
Có một số cải tiến đẩy xuống trong 9.6 có thể được quan tâm: wiki.postgresql.org/wiki/NewIn96#postgres_fdw
Jack nói hãy thử topanswers.xyz

Khi bạn nói bảng bình thường và bảng nước ngoài, bạn đang chạy trên cùng một bảng (cục bộ và từ xa) hoặc các bảng thực sự khác nhau (nó đọc như thể chúng), nếu chúng khác nhau, hãy kiểm tra việc lập chỉ mục trên máy chủ từ xa, đảm bảo chúng giống nhau vì bạn dường như đang đọc các nguồn thông tin hoàn toàn khác IntterraNearRealTimeUnitReflexes300sForeignso với IntterraNearRealTimeUnitReflexes300sidx_incident_date_time_300 tôi cho rằng những số 300 là như nhau, nhưng có thể đáng để kiểm tra nếu idx_incident_date_time_300chỉ mục tồn tại trên máy chủ nước ngoài
Ste Bov

2
Theo những gì tôi hiểu, các tập hợp (COUNT) không được đẩy đến máy chủ từ xa, điều này sẽ giải thích thời gian yêu cầu dài. Có vẻ như tính năng này sẽ xuất hiện trong pg 10 - depesz.com/2016/10/25/ trên
Jerome WAGNER

@JeromeWAGNER - Tuyệt vời
J-DawG

Câu trả lời:


7

Nếu bạn sử dụng use_remote_estimatehãy chắc chắn để chạy ANALYZE bảng ngoại (Tôi thấy các ước tính khá gần với trả về, có lẽ bạn đã làm điều đó). Ngoài ra, các cải tiến đẩy xuống không có sẵn trong phiên bản <9.5. Tôi cũng giả sử rằng bạn có cùng cấu trúc bảng trên máy chủ từ xa (bao gồm các chỉ mục). Nếu một bitmap là cần thiết do số lượng cardin thấp, nó sẽ không sử dụng chỉ mục do những hạn chế trong cơ chế đẩy xuống. Bạn có thể muốn giảm số lượng hàng trả về để buộc quét chỉ mục BTREE ( phạm vi dấu thời gian). Thật không may, không có cách nào rõ ràng để tránh SeqScan trên máy chủ từ xa nếu bộ lọc trả về + 10% số hàng của bảng (có thể thay đổi tỷ lệ phần trăm này nếu trình hoạch định cho rằng quét toàn bộ bảng rẻ hơn so với tìm kiếm đọc). Nếu bạn đang sử dụng SSD, có lẽ bạn sẽ thấy hữu ích để điều chỉnh random_page_cost).

Bạn có thể sử dụng CTE để cách ly hành vi GROUP BY:

WITH atable AS (
    SELECT "IncidentTypeCode"
    FROM PUBLIC ."IntterraNearRealTimeUnitReflexes300s"
    WHERE 
       ("IncidentDateTime" 
              BETWEEN '2016-05-01 00:00:00'::TIMESTAMP WITHOUT TIME ZONE 
                  AND '2016-05-02 00:00:00'::TIMESTAMP WITHOUT TIME ZONE)
)
SELECT atable."IncidentTypeCode", COUNT(atable.IncidentTypeCode) 
FROM atable
GROUP BY atable."IncidentTypeCode" 
ORDER BY atable."IncidentTypeCode";

1
Hiệu suất là như nhau khi sử dụng CTE. Sẽ thử cài đặt Random_page_cost mặc dù. Cảm ơn!
J-DawG
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.