Ràng buộc phân vùng không được sử dụng cho các phép nối liên quan đến các bảng được phân chia theo dấu thời gian


11

Tôi có một cấu trúc bảng được phân vùng như:

CREATE TABLE measurements (
    sensor_id bigint,
    tx timestamp,
    measurement int
);

CREATE TABLE measurements_201201(
    CHECK (tx >= '2012-01-01 00:00:00'::timestamp without time zone 
       AND tx < ('2012-01-01 00:00:00'::timestamp without time zone + '1 mon'::interval))    
)INHERITS (measurements);
CREATE INDEX ON measurements_201201(sensor_id);
CREATE INDEX ON measurements_201201(tx);
CREATE INDEX ON measurements_201201(sensor_id, tx);
....

Và như thế. Mỗi bảng có khoảng 20M hàng.

Nếu tôi truy vấn một mẫu cảm biến và mẫu dấu thời gian trong WHEREmệnh đề, kế hoạch truy vấn sẽ hiển thị các bảng chính xác được chọn và các chỉ mục đang được sử dụng, ví dụ:

SELECT *
FROM measurements
INNER JOIN sensors TABLESAMPLE BERNOULLI (0.01) USING (sensor_id)
WHERE tx BETWEEN '2015-01-04 05:00' AND '2015-01-04 06:00' 
    OR tx BETWEEN '2015-02-04 05:00' AND '2015-02-04 06:00' 
    OR tx BETWEEN '2014-03-05 05:00' AND '2014-04-07 06:00' ;

Tuy nhiên, nếu tôi sử dụng CTE hoặc đặt các giá trị dấu thời gian vào một bảng (không hiển thị, ngay cả với các chỉ mục trên bảng tạm thời).

WITH sensor_sample AS(
    SELECT sensor_id, start_ts, end_ts
    FROM sensors TABLESAMPLE BERNOULLI (0.01)
    CROSS JOIN (VALUES (TIMESTAMP '2015-01-04 05:00', TIMESTAMP '2015-01-04 06:00'),
        (TIMESTAMP '2015-02-04 05:00', TIMESTAMP '2015-02-04 06:00'),
        (TIMESTAMP  '2014-03-05 05:00', '2014-04-07 06:00') ) tstamps(start_ts, end_ts)
)

Một cái gì đó như dưới đây

SET constraint_exclusion = on;
SELECT * FROM measurements
INNER JOIN sensor_sample USING (sensor_id)
WHERE tx BETWEEN start_ts AND end_ts

Thực hiện quét chỉ mục trên mỗi bảng. Việc này vẫn còn tương đối nhanh, nhưng với sự phức tạp của các truy vấn ngày càng tăng, điều này có thể biến thành các lần quét seq, kết quả sẽ rất chậm để truy xuất ~ 40K hàng từ một tập hợp con giới hạn của các bảng được phân đoạn (4-5 trên 50).

Tôi lo ngại rằng một cái gì đó như thế này là vấn đề.

Đối với các biểu thức không tầm thường, bạn phải lặp lại điều kiện nguyên văn ít nhiều trong các truy vấn để làm cho trình hoạch định truy vấn Postgres hiểu nó có thể dựa vào ràng buộc CHECK. Ngay cả khi nó có vẻ dư thừa!

Làm cách nào tôi có thể cải thiện phân vùng và cấu trúc truy vấn để giảm khả năng chạy quét seq trên tất cả dữ liệu của mình?


1
câu hỏi tuyệt vời - nhưng sẽ tốt hơn nữa nếu bạn dán kết quả của EXPLAIN (
ANALYZE, BUFFERS

Câu trả lời:


1

Loại trừ dựa trên ràng buộc [CBE] được thực hiện ở giai đoạn đầu của lập kế hoạch truy vấn, ngay sau khi truy vấn được phân tích cú pháp, ánh xạ tới quan hệ thực tế và viết lại. ( nội bộ , giai đoạn Lập kế hoạch / Tối ưu hóa)

Công cụ lập kế hoạch không thể giả sử bất kỳ nội dung nào của bảng "sensor_sample".

Vì vậy, trừ khi bạn có các giá trị được mã hóa cứng trong truy vấn, trình hoạch định sẽ không loại trừ "phân vùng".

Tôi đoán điều gì xảy ra với biến thể CTE ... công cụ lập kế hoạch bị hạn chế do bạn sử dụng TABLESAMPLE và toàn bộ truy vấn phụ có thể được coi là không ổn định ngay cả khi nghĩa đen trong truy vấn phụ là tĩnh. ( đó chỉ là phỏng đoán của tôi, tôi không phải là chuyên gia về mã kế hoạch )

Về mặt tươi sáng, việc quét chỉ mục với kết quả âm tính rất nhanh. (quét nhiều trang nhất!) vì vậy trừ khi bạn có hơn 10000 phân vùng, tôi sẽ không bận tâm.

Vì vậy, để trả lời câu hỏi của bạn trực tiếp:

  • Bạn không thể cải thiện cấu trúc dữ liệu này nhiều hơn nữa.

  • Regardin quét chỉ số - chúng là giá rẻ;

  • Về quét liên tiếp - chúng được tránh khi có thể, như bạn thấy trên các ví dụ của riêng bạn.

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.