Почему индекс не используется для этого запроса? - PullRequest
0 голосов
/ 31 августа 2010

У меня есть таблица с 300K строк и индексом b-дерева в поле «оператор».Пока я выполняю этот запрос, он не использует индекс.«оператор» имеет тот же тип данных, что и dict.vw_dict_operator.id.

EXPLAIN SELECT  
    id,
    name
FROM
    dict.vw_dict_operator self 
WHERE

            EXISTS (
                SELECT 42 FROM ti.ti_flight_availability flight_avail
                WHERE flight_avail.operator = self.id
            )   
ORDER BY
    self.name 

"Sort  (cost=3349.66..3351.02 rows=545 width=18)"
"  Sort Key: dict_operator.name"
"  ->  Seq Scan on dict_operator  (cost=0.00..3324.89 rows=545 width=18)"
"        Filter: ((NOT trash) AND (subplan))"
"        SubPlan"
"          ->  Seq Scan on ti_flight_availability flight_avail  (cost=0.00..8513.66 rows=3750 width=0)"
"                Filter: (operator = $0)"

UPD: спасибо @gbn.Индекс также не используется при объединении таблиц

EXPLAIN SELECT self.id, self.name 
FROM dict.vw_dict_operator self JOIN ti.ti_flight_availability flight_avail
ON flight_avail.operator = self.id

"Nested Loop  (cost=0.00..92988.47 rows=228639 width=18)"
"  ->  Seq Scan on ti_flight_availability flight_avail  (cost=0.00..7754.33 rows=303733 width=4)"
"  ->  Index Scan using pk_dict_operator on dict_operator  (cost=0.00..0.27 rows=1 width=18)"
"        Index Cond: (dict_operator.id = flight_avail.operator)"
"        Filter: (NOT dict_operator.trash)"

Ответы [ 3 ]

2 голосов
/ 31 августа 2010

Почему вы не используете JOIN? А ты АНАЛИЗИРУЛ? Как насчет статистики? Проверьте pg_stats для этой таблицы, чтобы получить больше информации. reltuples и relpages в pg_class также интересны для таблицы и ее индексов.


Edit: JOIN ожидает 228639 строк. При последовательном сканировании ожидается 303733 строки, только дополнительная доля. Когда эти 100k записей повсюду, база данных все равно должна сканировать реляционные страницы. Последовательное сканирование будет быстрее, чем сканирование индекса, последовательное сканирование (быстрое) чтение последовательного хвоста, сканирование индекса будет двумя (!) Медленными случайными чтениями: информация из индекса и данные из таблица.

Если вы считаете, что план неправильный, АНАЛИЗИРУЙТЕ таблицу и покажите нам информацию из таблиц и индексов из pg_stats и pg_class.

ANALYZE;

SELECT relpage, reltuples WHERE relname = 'table_or_index_name';

SELECT * FROM pg_stats WHERE tablename = 'name of your table';
0 голосов
/ 31 августа 2010

Какой у вас индекс на dict.vw_dict_operator?

EXISTS - это форма JOIN (упрощенно, я знаю), и вполне возможно, что индекс игнорируется, потому что нет удобного JOIN для. Так что вместо этого он сканирует.

Edit:

план JOIN также не использует индекс для ti_flight_availability ... но вы заявляете, что у вас есть индекс для него?

0 голосов
/ 31 августа 2010

Будет ли он использовать индекс, если вы вместо этого выполните соединение?

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