Mam strukturę tabeli podzielonej na partycje, taką jak:
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);
....
I tak dalej. Każda tabela ma około 20 milionów wierszy.
Jeśli zapytam o próbkę czujników i próbkę znaczników czasu w WHERE
klauzuli, plan zapytań pokazuje prawidłowe wybrane tabele i używane indeksy, np .:
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' ;
Jeśli jednak użyję CTE lub wstawię wartości znaczników czasu do tabeli (nie pokazano, nawet z indeksami w tabeli tymczasowej).
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)
)
Coś jak poniżej
SET constraint_exclusion = on;
SELECT * FROM measurements
INNER JOIN sensor_sample USING (sensor_id)
WHERE tx BETWEEN start_ts AND end_ts
Wykonuje skanowanie indeksu na każdym stole. Co wciąż jest względnie szybkie, ale wraz ze wzrostem złożoności zapytań, może to przekształcić się w skanowanie sekwencji, co w rezultacie będzie bardzo powolne w pobieraniu ~ 40 000 wierszy z ograniczonego podzbioru tabel podzielonych na partycje (4-5 z 50).
Martwię się, że coś w tym jest problem.
W przypadku wyrażeń nietrywialnych musisz powtórzyć mniej lub bardziej dosłownie warunek w zapytaniach, aby planista zapytań Postgres zrozumiał, że może polegać na ograniczeniu CHECK. Nawet jeśli wydaje się to zbędne!
Jak mogę ulepszyć partycjonowanie i strukturę zapytań, aby zmniejszyć prawdopodobieństwo uruchamiania skanowania sekwencji na wszystkich moich danych?