Saya memiliki struktur tabel dipartisi seperti:
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);
....
Dan seterusnya. Setiap tabel memiliki sekitar 20 juta baris.
Jika saya meminta sampel sensor dan sampel cap waktu dalam WHERE
klausa, rencana kueri menunjukkan tabel yang benar yang dipilih dan indeks yang digunakanm misalnya:
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' ;
Namun, jika saya menggunakan CTE, atau memasukkan nilai cap waktu ke dalam tabel (tidak ditampilkan, bahkan dengan indeks pada tabel sementara).
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)
)
Sesuatu seperti di bawah ini
SET constraint_exclusion = on;
SELECT * FROM measurements
INNER JOIN sensor_sample USING (sensor_id)
WHERE tx BETWEEN start_ts AND end_ts
Melakukan pemindaian indeks pada setiap tabel. Yang masih relatif cepat, tetapi dengan meningkatnya kompleksitas kueri, ini dapat berubah menjadi pemindaian seq yang akan berakhir sangat lambat untuk mengambil ~ 40K baris dari subset terbatas dari tabel partisi (4-5 dari 50).
Saya khawatir sesuatu seperti ini adalah masalahnya.
Untuk ekspresi non-sepele Anda harus mengulangi kondisi kata demi kata dalam atau kurang lebih untuk membuat perencana kueri Postgres memahaminya dapat mengandalkan kendala PERIKSA. Bahkan jika itu tampak berlebihan!
Bagaimana saya bisa meningkatkan struktur partisi dan permintaan untuk mengurangi kemungkinan menjalankan pemindaian seq pada semua data saya?