2014-01-17 2 views
0

У меня есть таблица social_accounts с частичным индексом на колонке facebook_id где user_id IS NULL.Почему Postgresql не использует индекс для запроса IN?

Если я сделать простой запрос WHERE facebook_id = '123', используется индекс:

=> EXPLAIN for: SELECT "social_accounts".* FROM "social_accounts" WHERE (user_id IS NOT NULL) AND "social_accounts"."facebook_id" = '123' 
                QUERY PLAN 
-------------------------------------------------------------------------------------------------------------- 
Index Scan using index_social_accounts_on_facebook_id on social_accounts (cost=0.00..8.28 rows=1 width=345) 
    Index Cond: ((facebook_id)::text = '123'::text) 
    Filter: (user_id IS NOT NULL) 

, но если я делаю запрос с использованием IN он не использует индекс:

=> EXPLAIN for: SELECT "social_accounts".* FROM "social_accounts" WHERE (user_id IS NOT NULL) AND "social_accounts"."facebook_id" IN ('123', '456') 
              QUERY PLAN 
--------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on social_accounts (cost=8.53..16.36 rows=2 width=345) 
    Recheck Cond: ((facebook_id)::text = ANY ('{123,456}'::text[])) 
    Filter: (user_id IS NOT NULL) 
    -> Bitmap Index Scan on index_social_accounts_on_facebook_id (cost=0.00..8.52 rows=2 width=0) 
     Index Cond: ((facebook_id)::text = ANY ('{123,456}'::text[])) 
(5 rows) 

почему не делает он использует индекс во втором случае? любой способ ускорить этот запрос?

(обратите внимание, что для этого примера я усеченный массив, и я проверил со многими другими элементами, но с такими же, медленно, результатами)

+2

Почему, по вашему мнению, не использует индекс? В нем четко сказано, что он использует «Сканирование растрового индекса» на index_social_accounts_on_facebook_id' –

+0

Хорошо, я должен признать, что я пропустил это! Однако мне было интересно, почему сканирование битмап-карт и перепроверка Cond, о которых Денис объяснил. – Daniel

ответ

4

На самом деле, это является с использованием индекса. Просто делайте это по-другому.

Индексное сканирование посещает строки один за другим, перемещаясь с одной страницы диска на другой в случайном порядке.

Сканирование индексов растровых изображений начинается с фильтрации страниц диска для посещения, а затем поочередно посещает их по одному. Экран recheck cond заключается в том, что на каждой странице вам необходимо отфильтровать недопустимые строки.

Для крошечных номеров строк сканирование индекса является самым дешевым. Для большего количества строк сканирование растрового индекса становится самым дешевым. Для еще большего количества строк сканирование seq становится дешевле.

+0

Благодарим вас за это объяснение. Очень информативно! – RKitson

Смежные вопросы