Сканирование индекса растрового изображения происходит, когда результирующий набор будет иметь высокую степень избирательности по отношению к условиям поиска (т. Е. Имеется большой процент строк, которые удовлетворяют критериям поиска). В этом случае планировщик планирует сканировать весь индекс, формируя растровое изображение, из каких страниц на диске извлекаются данные (что происходит на этапе сканирования растрового изображения). Это лучше, чем последовательное сканирование, поскольку оно сканирует только соответствующие страницы на диске, пропуская страницы, о которых известно, что соответствующие данные не существуют. В зависимости от статистики, доступной оптимизатору, может быть не выгодно выполнять сканирование индекса или сканирование только индекса, но это все же лучше, чем последовательное сканирование.
Чтобы завершить ответ на вопрос,Сканирование только по индексу - это сканирование индекса, которое извлекает соответствующие данные, не посещая фактическую таблицу. Это потому, что соответствующие данные уже есть в индексе. Возьмем, к примеру, эту таблицу:
postgres=# create table foo (id int primary key, name text);
CREATE TABLE
postgres=# insert into foo values (generate_series(1,1000000),'foo');
INSERT 0 1000000
В столбце id
этой таблицы есть индекс, и предположим, что мы вызываем следующий запрос:
postgres=# EXPLAIN ANALYZE SELECT * FROM foo WHERE id < 100;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Scan using foo_pkey on foo (cost=0.42..10.25 rows=104 width=8) (actual time=0.012..1.027 rows=99 loops=1)
Index Cond: (id < 100)
Planning Time: 0.190 ms
Execution Time: 2.067 ms
(4 rows)
Этот запросприводит к сканированию индекса, поскольку сканирует индекс для строк с идентификатором <100, а затем обращается к фактической таблице на диске, чтобы извлечь другие столбцы, включенные в часть <code>* запроса SELECT
.
Однако предположим, что мы вызываем следующий запрос (уведомление SELECT id
вместо SELECT *
):
postgres=# EXPLAIN ANALYZE SELECT id FROM foo WHERE id < 100;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Index Only Scan using foo_pkey on foo (cost=0.42..10.25 rows=104 width=4) (actual time=0.019..0.996 rows=99 loops=1)
Index Cond: (id < 100)
Heap Fetches: 99
Planning Time: 0.098 ms
Execution Time: 1.980 ms
(5 rows)
Это приводит к сканированию только по индексу, поскольку запрашивается только столбец id
, иэто включено (естественно) в индекс, поэтому нет необходимости посещать фактическую таблицу на диске, чтобы получить что-либо еще. Это экономит время, но его появление очень ограничено.
Чтобы ответить на ваш вопрос об ограничении до 20 результатов, ограничение происходит после сканирования растровых индексов, поэтому время выполнения все равно будет тем же, независимо от того, ограничены ли вы20, 40 или какое-то другое значение. В случае сканирования по индексу / только по индексу исполнитель прекратит сканирование после того, как получит достаточно строк, как указано в предложении LIMIT
. В вашем случае, с помощью растрового сканирования кучи это невозможно