Эффективность запроса таблиц с временными метками с использованием CURRENT_TIMESTAMP - PullRequest
1 голос
/ 06 марта 2011

Учитывая следующее разбиение таблицы под PostgreSQL 9.0.3:

CREATE TABLE records (
  ts TIMESTAMP,
  ...
);

CREATE TABLE records_2010 (
  CHECK (ts >= '2010-01-01 00:00:00' AND ts < '2011-01-01 00:00:00')
) INHERITS (records);

CREATE TABLE records_2011 (
  CHECK (ts >= '2011-01-01 00:00:00' AND ts < '2012-01-01 00:00:00')
) INHERITS (records);

Я ожидал, что следующие запросы SELECT будут иметь один и тот же EXPLAINed план, обращаясь только к «records» и «records_2011», но они различаются:

BEGIN;
-- Assume CURRENT_TIMESTAMP is 9 a.m. on 5 March 2011
SELECT * FROM records WHERE ts >= '2011-03-05 09:00:00'; -- scans 2 tables
SELECT * FROM records WHERE ts >= CURRENT_TIMESTAMP;     -- scans all 3 tables
COMMIT;

Учитывая, что CURRENT_TIMESTAMP возвращает постоянное значение для продолжительности входящих в него транзакций, почему запрос с CURRENT_TIMESTAMP не использует преимущества разделения Postgres и сканирует только две таблицы?

UPDATE:

Это сейчас невозможно, но это признается областью для улучшения. PostgreSQL 9.1 может устранить это поведение в исполнителе запросов .

1 Ответ

5 голосов
/ 06 марта 2011

Если вы запускаете запрос впервые, PostgreSQL определяет план запроса.Это дорогостоящая операция, и результат кешируется.Таким образом, запрос должен работать и для будущих выполнений.

Вашему первому запросу никогда не потребуется records_2010, независимо от того, когда вы его выполняете.

Но во втором запросе используется переменная CURRENT_TIMESTAMP.Оптимизатор не знает, что время может только увеличиться, и создает план, который будет работать для любого значения ts.Это означает, что он должен выглядеть во всех трех таблицах.

...