Вот эта таблица и ее индексы. Эта таблица в производстве содержит ~ 50 миллионов строк.PostgreSQL игнорирует мой составной индекс
CREATE TABLE "public"."audit_page_loads" (
"id" int4 NOT NULL DEFAULT nextval('audit_page_loads_id_seq'::regclass),
"dt" timestamp(6) NULL,
"ip" varchar(255) COLLATE "default",
"method" varchar(255) COLLATE "default",
"action" varchar(255) COLLATE "default",
"elapsed" numeric(8,2) DEFAULT 0,
"views" numeric(8,2) DEFAULT 0,
"db" numeric(8,2) DEFAULT 0
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."audit_page_loads" ADD PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE;
CREATE INDEX "index_audit_page_loads_on_action" ON "public"."audit_page_loads" USING btree("action" COLLATE "default" ASC NULLS LAST);
CREATE INDEX "index_audit_page_loads_on_action_and_dt" ON "public"."audit_page_loads" USING btree("action" COLLATE "default" ASC NULLS LAST, dt ASC NULLS LAST);
Когда я запускаю этот выбор по таблице, для возврата результатов требуется около минуты. Я предполагал, что, поскольку у меня есть составной индекс для действия и dt, это заставит мой выбор делать сканирование индексов. Не так. Каждый запрос представляет собой последовательность сканирования
SELECT action, avg(elapsed), count(*)
FROM audit_page_loads
WHERE action != 'UsersController#login' and dt >= '2014-09-01'
GROUP BY action
Limit (cost=1685321.43..1685321.68 rows=20 width=32) (actual time=15900.954..15900.968 rows=20 loops=1)
-> HashAggregate (cost=1685321.43..1685321.80 rows=30 width=32) (actual time=15900.952..15900.965 rows=20 loops=1)
-> Seq Scan on audit_page_loads (cost=0.00..1646329.70 rows=5198897 width=32) (actual time=7.075..11826.963 rows=5820401 loops=1)
Filter: (((action)::text <> 'UsersController#login'::text) AND (dt >= '2014-09-01 00:00:00'::timestamp without time zone))
Rows Removed by Filter: 52614815
Total runtime: 15901.013 ms
При добавлении набор enable_seqscan = ложь;, чтобы выбрать, результаты мгновенные. .13 секунды, и я вижу в объяснении, что используется индекс index_audit_page_loads_on_action_and_dt. Зачем мне это нужно? И если я правильно понял, в том числе, что set enable_seqscan = false; нецелесообразно. Может ли кто-нибудь помочь мне здесь?
PostgreSQL 9.3.5 на x86_64-неизвестно-Linux-гну, составленный GCC (Ubuntu/Линаро 4.6.3-1ubuntu5) 4.6.3, 64-битный
Измените свой вопрос и вставьте результаты 'explain analysis SELECT action ...'. –