У меня есть таблица 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)
почему не делает он использует индекс во втором случае? любой способ ускорить этот запрос?
(обратите внимание, что для этого примера я усеченный массив, и я проверил со многими другими элементами, но с такими же, медленно, результатами)
Почему, по вашему мнению, не использует индекс? В нем четко сказано, что он использует «Сканирование растрового индекса» на index_social_accounts_on_facebook_id' –
Хорошо, я должен признать, что я пропустил это! Однако мне было интересно, почему сканирование битмап-карт и перепроверка Cond, о которых Денис объяснил. – Daniel