PostgreSQL - будет ли он когда-либо использовать два индекса в одной таблице?
Допустим, у вас есть таблица с некоторыми показателями:
create table mail
(
identifier serial primary key,
member text,
read boolean
);
create index on mail(member_identifier);
create index on mail(read);
Если вы теперь запросите несколько столбцов, которые имеют отдельные индексы, будет ли он когда-либо использовать оба индекса?
select * from mail where member = 'Jess' and read = false;
То есть, может ли PostgreSQL решить сначала использовать индекс на member
чтобы получить все письма для Джесс, а затем использовать индекс на read
получить все непрочитанные письма и затем пересечь оба результата, чтобы построить выходной набор?
Я знаю, что вы можете иметь индекс с несколькими столбцами (на (member, read)
в данном случае), но что будет, если у вас есть два отдельных индекса? Будет ли PostgreSQL выбирать только один или он может использовать оба в некоторых случаях?
Это не вопрос о конкретном запросе. Это общий вопрос, чтобы понять внутренности.
2 ответа
Postgres Документация по нескольким индексам запросов
В статье говорится, что это создаст абстрактное представление о том, где применяются оба индекса, а затем объединит результаты.
Чтобы объединить несколько индексов, система сканирует каждый необходимый индекс и подготавливает растровое изображение в памяти, предоставляя местоположения строк таблицы, которые, как сообщается, соответствуют условиям этого индекса. Затем растровые изображения объединяются и объединяются в соответствии с запросом. Наконец, фактические строки таблицы посещаются и возвращаются.
CREATE TABLE fifteen
(one serial PRIMARY KEY
, three integer not NULL
, five integer not NULL
);
INSERT INTO fifteen(three,five)
SELECT gs%33+5,gs%55+11
FROM generate_series(1,60000) gs
;
CREATE INDEX ON fifteen(three);
CREATE INDEX ON fifteen(five);
ANALYZE fifteen;
EXPLAIN ANALYZE
SELECT*
FROM fifteen
WHERE three= 7
AND five =13
;
Результат:
CREATE TABLE
INSERT 0 60000
CREATE INDEX
CREATE INDEX
ANALYZE
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on fifteen (cost=19.24..51.58 rows=31 width=12) (actual time=0.391..0.761 rows=364 loops=1)
Recheck Cond: ((five = 13) AND (three = 7))
Heap Blocks: exact=324
-> BitmapAnd (cost=19.24..19.24 rows=31 width=0) (actual time=0.355..0.355 rows=0 loops=1)
-> Bitmap Index Scan on fifteen_five_idx (cost=0.00..7.15 rows=1050 width=0) (actual time=0.136..0.136 rows=1091 loops=1)
Index Cond: (five = 13)
-> Bitmap Index Scan on fifteen_three_idx (cost=0.00..11.93 rows=1788 width=0) (actual time=0.194..0.194 rows=1819 loops=1)
Index Cond: (three = 7)
Planning time: 0.259 ms
Execution time: 0.796 ms
(10 rows)
Изменение {33,55} на {3,5} приведет к сканированию индекса только по одному индексу плюс условие дополнительного фильтра. (возможно, экономия будет слишком мала)