Понимание «сканирования кучи растрового изображения» и «сканирования индекса растрового изображения»


36

Я попытаюсь объяснить мои недоразумения на следующем примере.

Я не понимал основы из Bitmap Heap Scan Node. Рассмотрим запрос, SELECT customerid, username FROM customers WHERE customerid < 1000 AND username <'user100';план которого таков:

Bitmap Heap Scan on customers  (cost=25.76..61.62 rows=10 width=13) (actual time=0.077..0.077 rows=2 loops=1)
  Recheck Cond: (((username)::text < 'user100'::text) AND (customerid < 1000))
  ->  BitmapAnd  (cost=25.76..25.76 rows=10 width=0) (actual time=0.073..0.073 rows=0 loops=1)
        ->  Bitmap Index Scan on ix_cust_username  (cost=0.00..5.75 rows=200 width=0) (actual time=0.006..0.006 rows=2 loops=1)
              Index Cond: ((username)::text < 'user100'::text)
        ->  Bitmap Index Scan on customers_pkey  (cost=0.00..19.75 rows=1000 width=0) (actual time=0.065..0.065 rows=999 loops=1)
              Index Cond: (customerid < 1000)

Мое понимание этого узла :

Как объяснялось там , bitmap heap scanчтение блоков таблицы происходит в последовательном порядке, поэтому оно не приводит к накладным расходам при случайном доступе к таблице, что происходит просто так Index Scan.

После того Index Scan, как это было сделано, PostgreSQL не знает, как оптимально извлекать строки, чтобы избежать ненужного heap blocks reads(или hitsесли есть горячий кеш). Таким образом, чтобы понять это, он генерирует структуру ( Bitmap Index Scan), bitmapкоторая в моем случае генерируется путем создания двух битовых карт индексов и выполнения BITWISE AND. Поскольку растровое изображение было сгенерировано, теперь оно может оптимально читать таблицу в последовательном порядке, избегая ненужного heap I/O-operations.

Это место, где много вопросов.

ВОПРОС: У нас есть только растровое изображение. Как PostgreSQL знает по физическому порядку строк что-либо о физическом порядке строк? Или генерирует растровое изображение, чтобы любой его элемент можно было легко сопоставить с указателем на страницу? Если это так, это все объясняет, но это только мое предположение.

Итак, можем ли мы просто сказать, что bitmap heap scan -> bitmap index scanэто похоже на последовательное сканирование, но только на соответствующую часть таблицы?


Я написал объяснение некоторых из них здесь: stackoverflow.com/q/33100637/398670
Крейг Рингер

@CraigRinger Кажется, я не правильно объяснил, что я не понял. Конечно, как вы объяснили, у нас есть растровое изображение, по которому PostgreSQL последовательно читает таблицу. Я не понимаю, как он может выяснить фактический блок, обозначенный конкретным растровым изображением, например 001001010101011010101. Или это на самом деле не имеет значения, и все, что мы должны знать, это просто найти блок по его растровому изображению довольно быстро ...?
Сент-Антарио,

Ах, вы можете неправильно понять, что означает здесь «растровое изображение». Позвольте мне продолжить в редактировании.
Крейг Рингер,

@CraigRinger Может быть, я взял определение оттуда .
Сент-Антарио

Ответы:


52

Как PostgreSQL знает по физическому порядку строк что-либо о физическом порядке строк?

Растровое изображение - один бит на страницу кучи. Сканирование индекса битовой карты устанавливает биты на основе адреса страницы кучи, на которую указывает запись индекса.

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

Или генерирует растровое изображение, чтобы любой его элемент можно было легко сопоставить с указателем на страницу?

Нет, растровое изображение соответствует 1: 1 страницам кучи.

Я написал больше об этом здесь .


Хорошо, похоже, вы неправильно понимаете, что означает «растровое изображение» в этом контексте.

Это не битовая строка типа «101011», которая создается для каждой страницы кучи, каждого прочитанного индекса или чего-то еще.

Все растровое изображение представляет собой один битовый массив с таким количеством битов, сколько имеется страниц кучи в сканируемом отношении.

Одно растровое изображение создается при первом сканировании индекса, начиная со всех записей 0 (false). Когда бы ни находилась запись индекса, соответствующая условию поиска, адрес кучи, на который указывает эта запись индекса, рассматривается как смещение в битовой карте, и этот бит устанавливается в 1 (true). Таким образом, вместо просмотра страницы кучи непосредственно, сканирование индекса битовой карты ищет соответствующую битовую позицию в битовой карте.

Второе и последующее сканирование индекса растрового изображения делают то же самое с другими индексами и условиями поиска по ним.

Затем каждое растровое изображение объединяется. Результирующее растровое изображение имеет один бит для каждой страницы кучи, где биты имеют значение true, только если они были истинными во всех отдельных сканированиях индекса растрового изображения, то есть условие поиска соответствовало каждому сканированию индекса. Это единственные страницы кучи, которые нам нужно загружать и проверять. Так как каждая страница кучи может содержать несколько строк, мы должны изучить каждую строку, чтобы убедиться, что она соответствует всем условиям - вот о чем говорит часть «recheck cond».

Со всем этим важно понять, что адрес кортежа в записи индекса указывает на строку ctid, которая является комбинацией номера страницы кучи и смещения страницы кучи. Сканирование индекса растрового изображения игнорирует смещения, так как оно все равно проверит всю страницу и устанавливает бит, если какая-либо строка на этой странице соответствует условию.


Графический пример

Heap, one square = one page:
+---------------------------------------------+
|c____u_____X___u___X_________u___cXcc______u_|
+---------------------------------------------+
Rows marked c match customers pkey condition.
Rows marked u match username condition.
Rows marked X match both conditions.


Bitmap scan from customers_pkey:
+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
+---------------------------------------------+
One bit per heap page, in the same order as the heap
Bits 1 when condition matches, 0 if not

Bitmap scan from ix_cust_username:
+---------------------------------------------+
|000001000001000100010000000001000010000000010| bitmap 2
+---------------------------------------------+

Как только растровые изображения созданы побитовое И выполняется над ними:

+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
|000001000001000100010000000001000010000000010| bitmap 2
 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|000000000001000000010000000000000010000000000| Combined bitmap
+-----------+-------+--------------+----------+
            |       |              |
            v       v              v
Used to scan the heap only for matching pages:
+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+

Затем сканирование кучи растрового изображения ищет начало каждой страницы и читает страницу:

+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+
seek------->^seek-->^seek--------->^
            |       |              |
            ------------------------
            only these pages read

и каждая прочитанная страница затем проверяется на соответствие условию, поскольку на странице может быть> 1 строка, и не все обязательно соответствуют условию.


Ах, это то, что они имели в виду заполнения растрового изображения.
Сент-Антарио,

@ St.Antario Я добавил графику, чтобы объяснить
Крейг Рингер

Позвольте мне прояснить еще одну вещь о растровом сканировании. Вы сказали, что у нас есть битовая карта 1: 1 для кучи страниц, и мы можем определить страницу кучи по битовому индексу в битовой карте. Поскольку отношение может содержать страницы на диске в непоследовательном порядке (не кластеризованном), не совсем понятно, как мы можем определить адрес страницы, просто сместив его в растровое изображение. Я предполагаю, что планировщик знает, как вычислить адрес страницы по смещению для данного отношения . Это правда?
St.Antario

1
Таким образом, мы должны поместить все страницы, которые находятся на диске. Кроме того, данные отношения могут размещаться на двух или более дисках (поэтому трудно представить какой-либо линейный порядок страниц отношения ), поэтому определить фактическое смещение следующей страницы сложно. Потому что я считаю, что под «смещением» вы подразумевали фактическое физическое смещение, соответствующее физической позиции на диске.
St.Antario

2
PostgreSQL не заботится ни о каких дисках. Он заботится только о файлах в файловой системе . Логический файл для связи является линейным и непрерывным, и это то , что точечный рисунок закончен. (В файле может быть несколько экстентов, но они обрабатываются так, как будто они добавляются непрерывно, и растровое изображение находится над всеми ними). Вы смотрите на неправильный уровень абстракции. (Следует отметить, что растровое изображение при сканировании индекса растрового изображения также не рассчитывается планировщиком, оно является частью метода доступа к индексу btree и больше относится к исполнителю, чем к планировщику).
Крейг Рингер

3

Пожалуйста, обратитесь к моему сообщению в блоге https://rajeevrastogi.blogspot.in/2018/02/bitmap-scan-in-postgresql.html?showComment=1518410565792#c4647352762092142586 для подробного описания сканирования растровых изображений в PostgreSQL.

Общий краткий обзор функциональности растрового сканирования:

  1. Сканирование битовой карты запрашивает кортеж из сканирования битовой индексации.

  2. Сканирование индекса растрового изображения сканирует индекс согласно условию почти так же, как при обычном сканировании индекса. Но вместо того, чтобы возвращать TID (состоящий из номера страницы и смещения внутри него), соответствующий данным кучи, он добавляет эти TID в растровое изображение. Для простоты понимания, вы можете считать, что это растровое изображение содержит хэш всех страниц (хэшируется на основе номера страницы), и каждая запись страницы содержит массив всех смещений на этой странице.

  3. Затем Bitmap Heap Scan считывает растровое изображение, чтобы получить данные кучи, соответствующие сохраненному номеру страницы и смещению. Затем он проверяет видимость, квалификацию и т. Д. И возвращает кортеж на основе результатов всех этих проверок.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.