Индекс игнорирования PostgreSQL для столбца метки времени - PullRequest
5 голосов
/ 24 февраля 2012

У меня есть следующая таблица и созданный индекс:

CREATE TABLE cdc_auth_user
(
  cdc_auth_user_id bigint NOT NULL DEFAULT nextval('cdc_auth_user_id_seq'::regclass),
  cdc_timestamp timestamp without time zone DEFAULT ('now'::text)::timestamp without time zone,
  cdc_operation text,
  id integer,
  username character varying(30)
);

CREATE INDEX idx_cdc_auth_user_cdc_timestamp
          ON cdc_auth_user
       USING btree (cdc_timestamp);

Однако, когда я выполняю выборку с использованием поля отметки времени, индекс игнорируется, и мой запрос возвращает почти 10 секунд:

EXPLAIN SELECT *
          FROM cdc_auth_user
         WHERE cdc_timestamp BETWEEN '1900/02/24 12:12:34.818'
                             AND '2012/02/24 12:17:45.963';


Seq Scan on cdc_auth_user  (cost=0.00..1089.05 rows=30003 width=126)
  Filter: ((cdc_timestamp >= '1900-02-24 12:12:34.818'::timestamp without time zone) AND (cdc_timestamp <= '2012-02-24 12:17:45.963'::timestamp without time zone))

1 Ответ

2 голосов
/ 24 февраля 2012

Если результатов много, btree может быть медленнее, чем просто сканирование таблицы. Индексы btree на самом деле не предназначены для такого типа запроса «выбора диапазона», который вы здесь делаете; записи помещаются в большой несортированный файл, и индекс строится для этой несортированной группы, поэтому для каждого результата может потребоваться поиск диска после того, как он найден в btree. Конечно, btree можно легко прочитать по порядку, но результаты все равно нужно извлечь с диска.

Кластеризованные индексы решают эту проблему, упорядочивая фактические записи базы данных в соответствии с тем, что находится в btree, поэтому они действительно полезны для таких ранжированных запросов, как этот. Попробуйте вместо этого использовать кластерный индекс и посмотрите, как он работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...