Wicked
Новичок
Неправильно выбирается индекс
... что приводит к увеличению времени выполнения запроса в ~50000 раз
Есть таблица на 5гб с постами из высосанных фидов. Мы из нее хотим показать оные примерно так, как они показываются в гугл ридере. Т.е. where feed_id in (...) and pub_date between $a and $b.
Таблица:
Статистика:
Всего постов в таблице - 3.3млн.
Всего постов для инетерсующих нас фидах:
Всего постов из всех фидов, попадающих в интересующий нас диапазон дат
При пересечении условий (через AND) у нас тоже получается 52 записи, т.е. диапазоном дат не отсекается ни одной.
Ок... теперь сам запрос:
Меня это не устраивает. Для теста стартую транзакцию и дропаю индекс, который зачем-то используется этим запросом: db=# drop index "ext_feeder_item_pub_date_idx";
Перезапускаем запрос:
Собственно, мне, как обычно, интересны 2 вещи: кто виноват и что делать (кроме как дропать вредный индекс)? 
... что приводит к увеличению времени выполнения запроса в ~50000 раз

Есть таблица на 5гб с постами из высосанных фидов. Мы из нее хотим показать оные примерно так, как они показываются в гугл ридере. Т.е. where feed_id in (...) and pub_date between $a and $b.
Таблица:
Код:
db=# \d+ ext_feeder_item
Table "public.ext_feeder_item"
Column | Type | Modifiers | Description
----------------+--------------------------+--------------------------------------------------------------+-------------
id | bigint | not null default nextval('ext_feeder_item_id_seq'::regclass) |
feed_id | bigint | not null |
title | text | not null |
description | text | |
pub_date | timestamp with time zone | |
Indexes:
"ext_feeder_item_pkey" PRIMARY KEY, btree (id)
"ext_feeder_item_feed_id_pub_date_idx" btree (feed_id, pub_date)
"ext_feeder_item_pub_date_idx" btree (pub_date)
Всего постов в таблице - 3.3млн.
Всего постов для инетерсующих нас фидах:
Код:
SELECT count(*) FROM ext_feeder_item AS i WHERE i.feed_id IN (93912, 93922, 93930, 50621, 93946, 93955, 93964, 93971, 93976, 93981, 93988, 93991);
= 52.
Код:
SELECT count(*) FROM ext_feeder_item AS i WHERE '2008-01-16 00:23:04+00' <= pub_date AND pub_date <= '2008-03-16 18:17:10+00';
= 2.9млн
Ок... теперь сам запрос:
Код:
db=# EXPLAIN ANALYZE SELECT id FROM ext_feeder_item AS i WHERE i.feed_id IN (93912, 93922, 93930, 50621, 93946, 93955, 93964, 93971, 93976, 93981, 93988, 93991) \
AND '2008-01-16 00:23:04+00' <= pub_date AND pub_date <= '2008-03-16 18:17:10+00' ORDER BY i.pub_date ASC LIMIT 11 OFFSET 41;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=1359.01..1723.62 rows=11 width=16) (actual time=66178.925..78270.865 rows=11 loops=1)
-> Index Scan using ext_feeder_item_pub_date_idx on ext_feeder_item i (cost=0.00..780335.03 rows=23542 width=16) \
(actual time=44.502..78270.762 rows=52 l
Index Cond: (('2008-01-16 06:23:04+06'::timestamp with time zone <= pub_date) \
AND (pub_date <= '2008-03-17 00:17:10+06'::timestamp with time zone))
Filter: (feed_id = ANY ('{93912,93922,93930,50621,93946,93955,93964,93971,93976,93981,93988,93991}'::bigint[]))
Total runtime: 78270.946 ms
Перезапускаем запрос:
Код:
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=76288.36..76288.39 rows=11 width=16) (actual time=45.915..45.946 rows=11 loops=1)
-> Sort (cost=76288.26..76347.11 rows=23542 width=16) (actual time=45.834..45.885 rows=52 loops=1)
Sort Key: pub_date
Sort Method: quicksort Memory: 19kB
-> Bitmap Heap Scan on ext_feeder_item i (cost=687.70..75499.55 rows=23542 width=16) (actual time=39.338..45.698 rows=52 loops=1)
Recheck Cond: ((feed_id = ANY ('{93912,93922,93930,50621,93946,93955,93964,93971,93976,93981,93988,93991}'::bigint[])) \
AND ('2008-01-16 06:23:04+06'::timestamp with time zone <= pub_date) AND (pub_date <= '2008-03-17 00:17:10+06'::timestamp with time zone))
-> Bitmap Index Scan on ext_feeder_item_feed_id_pub_date_idx (cost=0.00..681.82 rows=23542 width=0) (actual time=39.288..39.288 rows=52 loops=1)
Index Cond: ((feed_id = ANY ('{93912,93922,93930,50621,93946,93955,93964,93971,93976,93981,93988,93991}'::bigint[])) \
AND ('2008-01-16 06:23:04+06'::timestamp with time zone <= pub_date) AND (pub_date <= '2008-03-17 00:17:10+06'::timestamp with time zone))
Total runtime: 46.025 ms // без explain analyze: Time: 1.404 ms
