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} приведет к сканированию индекса только по одному индексу плюс условие дополнительного фильтра. (возможно, экономия будет слишком мала)

Другие вопросы по тегам