Compare commits

..

No commits in common. "bfae9ba8c72345e98594981c7818c57386de6b91" and "fed7b2b63738150608e8cfdfbe6df22efda1221c" have entirely different histories.

55 changed files with 66 additions and 284 deletions

View File

@ -1,27 +0,0 @@
---
aliases:
- страница
- страницы
- страница БД
- Страница БД
- странице бд
tags:
- maturity/🌱
date: 2024-11-04
---
В базе данных страница — это базовая единица хранения данных, используемая для организации таблиц и индексов. Она представляет собой фиксированный блок данных (обычно 8 килобайт в PostgreSQL, но размер может варьироваться) и содержит строки таблицы или фрагменты индексов. Когда база данных выполняет запрос, она обращается к страницам, чтобы получить нужные строки, и может считывать их из диска или из кэша, где часто используемые страницы уже загружены в память.
База данных работает поверх операционной системы и поэтому использует [[../fundamental/Страница|страницы ОС]] для хранения своих страниц данных. Когда СУБД загружает страницу базы данных из диска, операционная система выделяет ей одну или несколько страниц оперативной памяти. В результате страницы базы данных хранятся в страницах памяти ОС.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]]
**Родитель**:: [[../fundamental/Страница|Страница]]
**Источник**::
**Создана**:: [[2024-11-04]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -6,8 +6,6 @@ tags:
- maturity/🌱 - maturity/🌱
date: 2024-10-23 date: 2024-10-23
--- ---
![[../../../meta/files/images/Pasted image 20241104202857.png]]
**Особенности:** **Особенности:**
- Основан на работе [[../../fundamental/structure/B-tree|B-tree]] дерева. - Основан на работе [[../../fundamental/structure/B-tree|B-tree]] дерева.
- Подходит для операций сравнения (`<`, `>`, `BETWEEN`), равенства (`=`) и сортировки. - Подходит для операций сравнения (`<`, `>`, `BETWEEN`), равенства (`=`) и сортировки.
@ -29,7 +27,7 @@ CREATE INDEX idx_name ON table_name (column_name);
**Создана**:: [[2024-10-23]] **Создана**:: [[2024-10-23]]
**Автор**:: **Автор**::
### Дополнительные материалы ### Дополнительные материалы
- [Владимир Ситников — B-tree индексы в базах данных на примере PostgreSQL - YouTube](https://www.youtube.com/watch?v=mnEU2_cwE_s) -
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -13,7 +13,7 @@ parents:
linked: linked:
- "[[Репликация в PostgreSQL]]" - "[[Репликация в PostgreSQL]]"
--- ---
В журнал попадают физические изменения, т.е. обновления страничек. Есть [[../DB page|страница]] в памяти, на ней лежат какие-то данные, мы с ней что-то сделали вот эту разницу мы записываем в журнал. В журнал попадают физические изменения, т.е. обновления страничек. Есть [[../../fundamental/Страница|страница]] в памяти, на ней лежат какие-то данные, мы с ней что-то сделали вот эту разницу мы записываем в журнал.
В WAL попадает всё: обновление таблиц, создание триггеров, создание хранимых процедур и так далее. В WAL попадает всё: обновление таблиц, создание триггеров, создание хранимых процедур и так далее.

View File

@ -12,7 +12,7 @@ date: 2024-03-31
- **Распухание индексов** (bloat) — это проблема увеличения размера индексов со временем, требующая переиндексации. - **Распухание индексов** (bloat) — это проблема увеличения размера индексов со временем, требующая переиндексации.
- [[Создание индекса в PostgreSQL]] - [[Создание индекса в PostgreSQL]]
- [[../Частичный индекс|Частичный индекс]] - [[../Частичный индекс]]
- [[Составной индекс в PostgreSQL]] - [[Составной индекс в PostgreSQL]]
**Типы индексов:** **Типы индексов:**
@ -22,10 +22,6 @@ date: 2024-03-31
- [[SP-GiST индекс в PostgreSQL|SP-GiST индекс]] - [[SP-GiST индекс в PostgreSQL|SP-GiST индекс]]
- [[GIN индекс в PostgreSQL|GIN индекс]] - [[GIN индекс в PostgreSQL|GIN индекс]]
- [[BRIN индекс в PostgreSQL|BRIN индекс]] - [[BRIN индекс в PostgreSQL|BRIN индекс]]
**Влияние обновления строки на индекс**
- **Обновление индексированной колонки.** По факту мы добавляем новую запись в индекс, а старую забываем. Старая остается мертвым грузом (bloat), индекс распухает, его нужно убрать vacuum.
- **Обновление не индексированной колонки.** Если строка в таблице остается на той же [[../DB page|странице бд]], то есть было место на странице, то индекс не меняется. Если строка не помещается, то добавляется новая запись в индекс, а старая остается мертвым грузом (bloat), индекс распухает, его нужно убрать vacuum.
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]] **Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]

View File

@ -26,15 +26,13 @@ EXPLAIN (FORMAT JSON) SELECT * FROM users WHERE id = 20;
> [!NOTE] Analyze > [!NOTE] Analyze
> `EXPLAIN` не выполняет сам запрос, поэтому результаты будут приблизительными. Для более точного анализа можно добавить ключевое слово `ANALYZE`, и тогда `EXPLAIN` также выполнит запрос. > `EXPLAIN` не выполняет сам запрос, поэтому результаты будут приблизительными. Для более точного анализа можно добавить ключевое слово `ANALYZE`, и тогда `EXPLAIN` также выполнит запрос.
## Стоимость выполнения запроса (cost) ## Стоимость выполнения запроса (cost)
PostgreSQL использует условные единицы для обозначения стоимости выполнения запроса — `cost`. Один `cost` примерно соответствует времени, затраченному на извлечение одной [[../DB page|страницы]] при последовательном сканировании (Seq Scan). PostgreSQL использует условные единицы для обозначения стоимости выполнения запроса — `cost`. Один `cost` примерно соответствует времени, затраченному на извлечение одного блока данных размером 8 килобайт при последовательном сканировании (Seq Scan).
Часто используются два значения `cost`: Часто используются два значения `cost`:
- **Первое значение**: стоимость до начала получения первых результатов. - **Первое значение**: стоимость до начала получения первых результатов.
- **Второе значение**: полная стоимость выполнения запроса. - **Второе значение**: полная стоимость выполнения запроса.
Если оценочное значение `rows` слишком низкое по сравнению с фактическим количеством строк, это может означать, что статистика таблицы устарела. В таком случае необходимо выполнить `ANALYZE` для обновления статистики и улучшения качества планирования запросов. Если оценочное значение `rows` слишком низкое по сравнению с фактическим количеством строк, это может означать, что статистика таблицы устарела. В таком случае необходимо выполнить `ANALYZE` для обновления статистики и улучшения качества планирования запросов.
Также PostgreSQL умеет считать количество обращений к диску. Для этого нужно добавить опцию `buffres`: `explain (analize, buffres)`. Это не время на чтение.
## Виды проходов по таблице и индексу ## Виды проходов по таблице и индексу
- **Seq Scan**: последовательный просмотр всей таблицы. Это наиболее медленный вариант и обычно нежелателен. Решение — добавить [[../Индекс базы данных|индекс]], чтобы ускорить выборку данных. - **Seq Scan**: последовательный просмотр всей таблицы. Это наиболее медленный вариант и обычно нежелателен. Решение — добавить [[../Индекс базы данных|индекс]], чтобы ускорить выборку данных.
- **Index Scan**: использование [[../Индекс базы данных|индекса]] для просмотра таблицы. - **Index Scan**: использование [[../Индекс базы данных|индекса]] для просмотра таблицы.

View File

@ -5,7 +5,7 @@ tags:
date: 2024-03-31 date: 2024-03-31
linked: linked:
--- ---
[[../Составной индекс в БД|Составные индексы]] в PostgreSQL позволяют ускорить выполнение запросов, в которых используются несколько колонок одновременно. Однако важно учитывать особенности их частичного использования. [[../Составные индексы в БД|Составные индексы]] в PostgreSQL позволяют ускорить выполнение запросов, в которых используются несколько колонок одновременно. Однако важно учитывать особенности их частичного использования.
При выполнении запроса составной индекс может использоваться до первого неравенства включительно. Это означает, что при встрече оператора неравенства (`>`, `<`, `>=`, `<=`) индекс перестает быть эффективным для последующих колонок. При выполнении запроса составной индекс может использоваться до первого неравенства включительно. Это означает, что при встрече оператора неравенства (`>`, `<`, `>=`, `<=`) индекс перестает быть эффективным для последующих колонок.
@ -17,7 +17,7 @@ linked:
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]] **Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]
**Родитель**:: [[../Составной индекс в БД|Составной индекс в БД]], [[Индекс в PostgreSQL]] **Родитель**:: [[../Составные индексы в БД|Составные индексы в БД]], [[Индекс в PostgreSQL]]
**Источник**:: **Источник**::
**Автор**:: **Автор**::
**Создана**:: **Создана**::

View File

@ -1,24 +0,0 @@
---
aliases:
- таблица
- таблице
tags:
- maturity/🌱
date: 2024-11-04
---
Таблица - это гомогенное множество кортежей.
Таблица разбивается на [[../DB page|страницы]].
***
## Мета информация
**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-11-04]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -48,7 +48,7 @@ date: 2024-10-11
**Какие бывают индексы?** **Какие бывают индексы?**
- **Уникальные и неуникальные.** Уникальные индексы обеспечивают уникальность значений в столбцах. Неуникальные индексы допускают повторяющиеся значения. - **Уникальные и неуникальные.** Уникальные индексы обеспечивают уникальность значений в столбцах. Неуникальные индексы допускают повторяющиеся значения.
- **Простые и составные.** Простые индексы создаются для одного столбца, а [[Составной индекс в БД|составные]] — для нескольких столбцов. - **Простые и составные.** Простые индексы создаются для одного столбца, а [[Составные индексы в БД|составные]] — для нескольких столбцов.
- **Кластерные и некластерные.** Кластерные индексы определяют физическое расположение данных на диске, а некластерные индексы хранят указатели на строки таблицы. - **Кластерные и некластерные.** Кластерные индексы определяют физическое расположение данных на диске, а некластерные индексы хранят указатели на строки таблицы.
**Реализации:** **Реализации:**
@ -67,9 +67,9 @@ date: 2024-10-11
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Индекс в MySQL]]
- [[Индекс в PostgreSQL]] - [[Индекс в PostgreSQL]]
- [[Индекс в MySQL]]
- [[Составные индексы в БД]]
- [[Покрывающий индекс]] - [[Покрывающий индекс]]
- [[Составной индекс в БД]]
<!-- SerializedQuery END --> <!-- SerializedQuery END -->

View File

@ -1,30 +0,0 @@
---
aliases:
tags:
- maturity/🌱
- best-practices
date: 2024-11-05
---
Представьте, что вам нужно поддерживать уникальность данных, например, адресов электронной почты в таблице базы данных. Однако в таблице есть строки, [[../Tombstone|помеченные как удаленные]] с помощью поля `deleted_at`, и они также остаются в базе данных. В такой ситуации создание уникального индекса на поле с электронной почтой становится невозможным из-за дублирующихся значений. [[Частичный индекс|Частичный индекс]] решает эту проблему, позволяя включать в индекс только записи, которые не помечены как удаленные.
В PostgreSQL добавление уникального индекса для активных пользователей выглядит так:
```sql
CREATE UNIQUE INDEX users_email_uniq ON users (
email
) WHERE deleted_at IS NULL;
```
В этом случае строки, у которых `deleted_at` не задан, включаются в индекс, а остальные игнорируются, что делает индекс более компактным и эффективным.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-11-05]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -1,25 +0,0 @@
---
aliases:
tags:
- maturity/🌱
- hack
date: 2024-11-05
---
Если в таблице много записей с одинаковыми значениями (низкая [[Селективность колонки|селективность]]), и необходимо индексировать только записи с уникальными или более специфичными значениями, то можно использовать проблему низкой селективности для повышения эффективности запросов.
Когда менее селективные поля находятся в начале индекса, на одной [[DB page|странице]] в памяти базы данных группируются записи с одинаковыми значениями по этим полям. Это позволяет при поиске уникального значения считывать меньше [[DB page|страниц]] из памяти, что в некоторых случаях может улучшить производительность.
![[../../meta/files/images/Pasted image 20241105002717.png]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-11-05]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -1,17 +1,18 @@
--- ---
aliases: aliases:
- Составные индексы - Составные индексы
- многоколоночный индекс
tags: tags:
- maturity/🌱 - maturity/🌱
date: 2024-06-16 date: 2024-06-16
--- ---
Составной индекс — это индекс, включающий несколько полей, который используется для повышения производительности запросов, фильтрующих данные сразу по нескольким колонкам. Составным называется индекс, который включает в себя сразу несколько полей. Он используется для повышения производительности запросов, которые фильтруют данные по нескольким колонкам одновременно.
Проще всего представить составной индекс не как последовательность индексов по отдельным колонкам, а как индекс по объединённым значениям этих колонок. Поэтому порядок столбцов в составном индексе имеет значение.== Он влияет на эффективность индекса, и поэтому чаще всего ==наиболее [[Селективность колонки|селективные]] поля следует располагать первыми== для максимальной производительности. ==SQL-запросы также должны учитывать этот порядок== для оптимального использования индекса. ==В составных индексах важен порядок столбцов.== Порядок колонок в индексе влияет на его эффективность, и более [[Селективность колонки|селективные]] поля должны идти первыми, чтобы максимизировать производительность. SQL-запросы также должны следовать этому порядку для оптимального использования индекса.
Однако, есть исключительные ситуации из этого правила: При поиске по составному индексу значения колонок сравниваются по порядку, что делает порядок следования колонок критически важным для эффективности запросов.
- [[Использование малоселективных полей для оптимизации чтения страниц]]
> [!WARNING] Количество параметров
> Составной индекс из 2-3 полей обычно считается нормальным и эффективно поддерживаемым. Если количество колонок в индексе превышает три, следует тщательно анализировать его использование, чтобы избежать излишней нагрузки на производительность.
**Преимущества:** **Преимущества:**
- **Оптимизация дискового пространства**: ==Один составной индекс может заменить несколько простых индексов==, что экономит дисковое пространство. - **Оптимизация дискового пространства**: ==Один составной индекс может заменить несколько простых индексов==, что экономит дисковое пространство.
@ -21,12 +22,6 @@ date: 2024-06-16
- **Высокие накладные расходы при обновлении**: Каждый раз при вставке, обновлении или удалении данных, которые попадают в составной индекс, СУБД должна обновлять весь индекс, что может увеличивать время выполнения таких операций. - **Высокие накладные расходы при обновлении**: Каждый раз при вставке, обновлении или удалении данных, которые попадают в составной индекс, СУБД должна обновлять весь индекс, что может увеличивать время выполнения таких операций.
- Старайтесь минимизировать использование неравенств в начале составных индексов, так как это может ограничить их применение для последующих колонок. - Старайтесь минимизировать использование неравенств в начале составных индексов, так как это может ограничить их применение для последующих колонок.
> [!WARNING] Количество параметров
> Составной индекс из 2-3 полей обычно считается нормальным и эффективно поддерживаемым. Если количество колонок в индексе превышает три, следует тщательно анализировать его использование, чтобы избежать излишней нагрузки на производительность.
Создание составного индекса: Создание составного индекса:
```sql ```sql
CREATE INDEX idx_example ON table_name (column_a, column_b); CREATE INDEX idx_example ON table_name (column_a, column_b);

View File

@ -1,44 +0,0 @@
---
aliases:
tags:
- maturity/🌱
- best-practices
date: 2024-11-05
---
Часто в приложениях есть таблицы, которые содержат колонку статуса (`state`). Обычно статус разделяет записи на "обработанные" и "необработанные". Индекс нам часто нужен именно по необработанным данным. Создавая [[Частичный индекс|частичный индекс]] только по необработанным данным, мы можем ускорить выполнение запроса и уменьшить размер индекса.
Возьмем типичную табличку, в которой есть какие-то статусы мы хотим находить данные по этому статусу.
![300](../../meta/files/images/Pasted%20image%2020240331095959.png)
![600](../../meta/files/images/Pasted%20image%2020240331100144.png)
Часто появляется желание сделать индекс по полю статуса:
![600](../../meta/files/images/Снимок%20экрана%202024-03-31%20в%2010.07.02.png)
Но по факту мы индексируем поле, которое имеет небольшую [селективность](../../dev/database/Селективность%20колонки.md). Такой индекс не эффективный.
Хороший вариант в данном случае:
![600](../../meta/files/images/Снимок%20экрана%202024-03-31%20в%2010.13.39.png)
Почти идеальный:
![600](../../meta/files/images/Снимок%20экрана%202024-03-31%20в%2010.15.06.png)
![500](../../meta/files/images/Pasted%20image%2020240331101612.png)
Идеальный. Совмещаем и [[postgresql/Составной индекс в PostgreSQL|составной индекс]] и частичный.
![[../../meta/files/images/Pasted image 20241021225124.png]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Базы Данных|00 Базы Данных]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-11-05]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -26,8 +26,46 @@ WHERE fk_id IS NOT NULL;
**Когда использовать частичные индексы:** **Когда использовать частичные индексы:**
- Когда необходимо уменьшить размер индекса за счёт исключения ненужных записей, что позволяет сэкономить место на диске и ускорить операции поиска. - Когда необходимо уменьшить размер индекса за счёт исключения ненужных записей, что позволяет сэкономить место на диске и ускорить операции поиска.
- [[Использование малоселективных полей для оптимизации чтения страниц]] - Когда таблица содержит большое количество записей с одинаковыми значениями (низкая [[Селективность колонки|селективность]]), и вам нужно индексировать только те записи, которые имеют уникальные или более специфичные значения.
- [[Таблицы с колонкой статуса]]. В ситуациях, когда индекс нужен для работы с данными, которые соответствуют определённому условию, например, только "необработанные" записи. - В ситуациях, когда индекс нужен для работы с данными, которые соответствуют определённому условию, например, только "необработанные" записи.
## Применение частичных индексов
### Таблицы с колонкой статуса
Часто в приложениях есть таблицы, которые содержат колонку статуса (`state`). Обычно статус разделяет записи на "обработанные" и "необработанные". Индекс нам часто нужен именно по необработанным данным. Создавая частичный индекс только по необработанным данным, мы можем ускорить выполнение запроса и уменьшить размер индекса.
Возьмем типичную табличку, в которой есть какие-то статусы мы хотим находить данные по этому статусу.
![300](../../meta/files/images/Pasted%20image%2020240331095959.png)
![600](../../meta/files/images/Pasted%20image%2020240331100144.png)
Часто появляется желание сделать индекс по полю статуса:
![600](../../meta/files/images/Снимок%20экрана%202024-03-31%20в%2010.07.02.png)
Но по факту мы индексируем поле, которое имеет небольшую [селективность](../../dev/database/Селективность%20колонки.md). Такой индекс не эффективный.
Хороший вариант в данном случае:
![600](../../meta/files/images/Снимок%20экрана%202024-03-31%20в%2010.13.39.png)
Почти идеальный:
![600](../../meta/files/images/Снимок%20экрана%202024-03-31%20в%2010.15.06.png)
![500](../../meta/files/images/Pasted%20image%2020240331101612.png)
Идеальный. Совмещаем и [[postgresql/Составной индекс в PostgreSQL|составной индекс]] и частичный.
![[../../meta/files/images/Pasted image 20241021225124.png]]
### Для мягкого удаления
Представьте, что вам нужно поддерживать уникальность данных, например, адресов электронной почты в таблице базы данных. Однако в таблице есть строки, [[../Tombstone|помеченные как удаленные]] с помощью поля `deleted_at`, и они также остаются в базе данных. В такой ситуации создание уникального индекса на поле с электронной почтой становится невозможным из-за дублирующихся значений. Частичный индекс решает эту проблему, позволяя включать в индекс только записи, которые не помечены как удаленные.
В PostgreSQL добавление уникального индекса для активных пользователей выглядит так:
```sql
CREATE UNIQUE INDEX users_email_uniq ON users (
email
) WHERE deleted_at IS NULL;
```
В этом случае строки, у которых `deleted_at` не задан, включаются в индекс, а остальные игнорируются, что делает индекс более компактным и эффективным.
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../meta/zero/00 PostgreSQL|00 PostgreSQL]] **Область**:: [[../../meta/zero/00 PostgreSQL|00 PostgreSQL]]

View File

@ -12,10 +12,9 @@ date: 2024-01-29
- Узел содержит множество элементов, что позволяет хранить больше данных в одном месте. - Узел содержит множество элементов, что позволяет хранить больше данных в одном месте.
- Каждый узел представляет собой [[../Страница|страничку]] на диске, что снижает издержки на чтение. - Каждый узел представляет собой [[../Страница|страничку]] на диске, что снижает издержки на чтение.
- В каждом узле есть ссылки на следующий и предыдущий узлы (характерно для B+tree). - В каждом узле есть ссылки на следующий и предыдущий узлы (характерно для B+tree).
- В листьях дерева могут храниться сами данные или указатели на данные, то есть ссылаются на таблицу. - В узлах дерева могут храниться сами данные или указатели на данные.
- Элементы в узле отсортированы, что делает поиск более эффективным и позволяет создавать деревья с небольшой высотой, тем самым уменьшая количество обращений к диску. - Элементы в узле отсортированы, что делает поиск более эффективным и позволяет создавать деревья с небольшой высотой, тем самым уменьшая количество обращений к диску.
- Значения в узлах могут быть не уникальными. - Значения в узлах могут быть не уникальными.
- Обычно высота дерева не больше 3-4 уровней.
## Параметр t ## Параметр t
Параметр `t` определяет количество элементов в узле дерева. Параметр `t` определяет количество элементов в узле дерева.
- В каждом узле должно быть не менее `t-1` и не более `2t-1` ключей. Это правило важно для поддержания сбалансированности дерева, так как позволяет равномерно распределять элементы между узлами и поддерживать эффективную высоту дерева, что, в свою очередь, обеспечивает высокую производительность операций поиска. - В каждом узле должно быть не менее `t-1` и не более `2t-1` ключей. Это правило важно для поддержания сбалансированности дерева, так как позволяет равномерно распределять элементы между узлами и поддерживать эффективную высоту дерева, что, в свою очередь, обеспечивает высокую производительность операций поиска.
@ -32,23 +31,13 @@ date: 2024-01-29
- Поиск четных или нечетных чисел. - Поиск четных или нечетных чисел.
- Поиск суффиксов (`LIKE '%c'` — неэффективно). - Поиск суффиксов (`LIKE '%c'` — неэффективно).
## Поиск в B-tree ## Поиск в B-tree
Рассмотрим пример поиска значения `27`.
![](../../../meta/files/images/Pasted%20image%2020240129193115.png)
Значения в узлах могут быть не уникальными. Например, если значение `27` встречается дважды, поиск продолжается, переходя в следующий узел. Чтобы облегчить этот процесс, блоки на одном уровне связаны, создавая связный список.
Алгоритм поиска аналогичен [[Бинарное дерево поиска|бинарному дереву]], но выбор осуществляется из нескольких вариантов, а не из двух. Поиск выполняется за `O(t logt(n))`, но количество обращений к диску — `O(logt(n))`. Алгоритм поиска аналогичен [[Бинарное дерево поиска|бинарному дереву]], но выбор осуществляется из нескольких вариантов, а не из двух. Поиск выполняется за `O(t logt(n))`, но количество обращений к диску — `O(logt(n))`.
Рассмотрим пример поиска значения `5`. Начинаем с корневого блока, он всегда один. 5 больше 1, но меньше 7, поэтому идем в левую часть индекса.
![[../../../meta/files/images/Pasted image 20241104203100.png]]
Видим, что 5 больше чем 4, поэтому идем по ссылке на 4
![[../../../meta/files/images/Pasted image 20241104203423.png]]
И там уже мы находим нашу 5.
![[../../../meta/files/images/Pasted image 20241104203446.png]]
А пятерка в свою очередь указывает на место в таблице, и мы можем достать оттуда данные.
![[../../../meta/files/images/Pasted image 20241104203517.png]]
Значения в узлах могут быть не уникальными. Например, если значение `5` встречается дважды, поиск продолжается, переходя в следующий узел. Чтобы облегчить этот процесс, блоки на одном уровне связаны, создавая связный список.
## Добавление в B-tree ## Добавление в B-tree
Представим, что нужно вставить значение `15` в уже существующее дерево. Представим, что нужно вставить значение `15` в уже существующее дерево.

View File

@ -3,11 +3,12 @@ aliases:
- страницы - страницы
- страниц - страниц
- страничку - страничку
- страницы ОС
- Страница ОС
tags: tags:
- maturity/🌱 - maturity/🌱
date: 2024-09-17 date: 2024-09-17
zero-link:
parents:
linked:
--- ---
Страница это непрерывный блок памяти фиксированного размера. Страница это непрерывный блок памяти фиксированного размера.
@ -38,6 +39,3 @@ date: 2024-09-17
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[DB page]]
<!-- SerializedQuery END -->

View File

@ -1,37 +0,0 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-11-04
---
```
L1 cache reference ......................... 0.5 ns
Branch mispredict ............................ 5 ns
L2 cache reference ........................... 7 ns
Mutex lock/unlock ........................... 25 ns
Main memory reference ...................... 100 ns
Compress 1K bytes with Zippy ............. 3,000 ns = 3 µs
Send 2K bytes over 1 Gbps network ....... 20,000 ns = 20 µs
SSD random read ........................ 150,000 ns = 150 µs
Read 1 MB sequentially from memory ..... 250,000 ns = 250 µs
Round trip within same datacenter ...... 500,000 ns = 0.5 ms
Read 1 MB sequentially from SSD* ..... 1,000,000 ns = 1 ms
Disk seek ........................... 10,000,000 ns = 10 ms
Read 1 MB sequentially from disk .... 20,000,000 ns = 20 ms
Send packet CA->Netherlands->CA .... 150,000,000 ns = 150 ms
```
![[../../meta/files/images/Pasted image 20241104204304.png]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-11-04]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -1,23 +0,0 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-11-05
---
-
- [[2024-11-05]]. [Владимир Ситников — B-tree индексы в базах данных на примере PostgreSQL - YouTube](https://www.youtube.com/watch?v=mnEU2_cwE_s)
- [[2024-11-05]]. [[../source/lecture/Доклад. Могут ли Virtual threads заменить Webflux|Доклад. Могут ли Virtual threads заменить Webflux]]
- [[2024-11-05]]. [[../source/lecture/Доклад. Индексы в PostgreSQL. Как понять, что создавать|Доклад. Индексы в PostgreSQL. Как понять, что создавать]]
***
## Мета информация
**Область**:: [[../source/00 Источники|00 Источники]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-11-05]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -79,7 +79,6 @@ enableToc: false
**По типу контента:** **По типу контента:**
#content/opinion - Мое субъективное мнение по какой-то теме, по какому-то вопросу. #content/opinion - Мое субъективное мнение по какой-то теме, по какому-то вопросу.
#content/problem - Заметки, которые появились для решения проблем, с которыми я сталкивался.
#content/checklist - Различные полезные чек-листы. #content/checklist - Различные полезные чек-листы.
#type/archive - Архивные заметки. Их обновление не планируется, так как тема потеряла для меня интерес. #type/archive - Архивные заметки. Их обновление не планируется, так как тема потеряла для меня интерес.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 614 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 668 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 716 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

View File

@ -1 +0,0 @@
f7acfd614fc477ebff10b74de2d716ed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

View File

@ -1 +0,0 @@
933b38087b1601e6864908001b041df5

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

View File

@ -1 +0,0 @@
e82618e260f128c6cd048561af961e44

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

View File

@ -1 +0,0 @@
611a31d49324aab65ef65af0d5710ad7

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

View File

@ -1 +0,0 @@
bf46eb6f9a60ee2907f1030ceb9ce2cf

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1 +0,0 @@
035fd400699ca217a05fbe1e517d12a8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

View File

@ -1 +0,0 @@
b46e120ce165d4f7a8ea5df8c60a4d31

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

View File

@ -1 +0,0 @@
f7acfd614fc477ebff10b74de2d716ed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

View File

@ -1 +0,0 @@
933b38087b1601e6864908001b041df5

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -1 +0,0 @@
e82618e260f128c6cd048561af961e44

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

View File

@ -1 +0,0 @@
611a31d49324aab65ef65af0d5710ad7

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -1 +0,0 @@
bf46eb6f9a60ee2907f1030ceb9ce2cf

View File

@ -1 +0,0 @@
035fd400699ca217a05fbe1e517d12a8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

View File

@ -1 +0,0 @@
b46e120ce165d4f7a8ea5df8c60a4d31

View File

@ -19,7 +19,6 @@ title: PostgreSQL
- Изменение данных не заменяет строчку физически в памяти, а добавляет новую версию строки. Устаревшие строки через какое-то время помечаются и в них пишутся новые данные. - Изменение данных не заменяет строчку физически в памяти, а добавляет новую версию строки. Устаревшие строки через какое-то время помечаются и в них пишутся новые данные.
- Если транзакции нужно выполнить операцию с данными, с которыми работает другая транзакция, то она может встать в очередь. - Если транзакции нужно выполнить операцию с данными, с которыми работает другая транзакция, то она может встать в очередь.
- В логи попадают не все запросы. Это настраивается конфигурационными параметрами. Если логировать все запросы, то просядет производительность. - В логи попадают не все запросы. Это настраивается конфигурационными параметрами. Если логировать все запросы, то просядет производительность.
- Типичный размер [[../../dev/database/DB page|страницы]] 8 килобайт. На страницу помещается ~ 100 записей.
## Дополнительные материалы ## Дополнительные материалы
- [pg_utils](../../dev/database/postgresql/pg_utils.md) - [pg_utils](../../dev/database/postgresql/pg_utils.md)

View File

@ -35,7 +35,7 @@ linked:
## Заметки ## Заметки
- Классические СУБД хранят данные в двух местах: на диске и в памяти. - Классические СУБД хранят данные в двух местах: на диске и в памяти.
- [[../../dev/database/DB page|Страница БД]] модифицируется сначала в оперативной памяти, потом попадает на диск. - [[../../dev/fundamental/Страница|Страница]] модифицируется сначала в оперативной памяти, потом попадает на диск.
- ![](Pasted%20image%2020240531082744.png) - ![](Pasted%20image%2020240531082744.png)
- Часто думают, что реляционная таблица — это массив. Некоторые даже думают, что это двумерный массив. На самом деле, это гораздо более сложная штука. Это мультимножество набор определенного сорта кортежей, над которым не задано порядка. В SQL-таблице нет порядка. Это важно. И, как результат, когда вы делаете SELECT* из БД (просканировать все записи), результат выполнения запроса может меняться строчки могут быть в одном порядке, а могут и в другом. Про это нужно помнить. - Часто думают, что реляционная таблица — это массив. Некоторые даже думают, что это двумерный массив. На самом деле, это гораздо более сложная штука. Это мультимножество набор определенного сорта кортежей, над которым не задано порядка. В SQL-таблице нет порядка. Это важно. И, как результат, когда вы делаете SELECT* из БД (просканировать все записи), результат выполнения запроса может меняться строчки могут быть в одном порядке, а могут и в другом. Про это нужно помнить.
- Профиль нагрузки на реляционную базу данных выглядит следующим образом: 80% запросов это чтение, 20% запросов это запись. Если запросов на запись больше, то возможно реляционная база данных вам не подходит. - Профиль нагрузки на реляционную базу данных выглядит следующим образом: 80% запросов это чтение, 20% запросов это запись. Если запросов на запись больше, то возможно реляционная база данных вам не подходит.

View File

@ -4,15 +4,11 @@ tags:
date: 2024-10-02 date: 2024-10-02
--- ---
Здесь собраны ссылки на заметки, в которых я анализирую прочитанный/просмотренный материал. Здесь собраны ссылки на заметки, в которых я анализирую прочитанный/просмотренный материал.
- [[../dev/Посмотренные доклады по разработке|Посмотренные доклады по разработке]]
-
## Доклады ## Доклады
<!-- QueryToSerialize: LIST FROM #type/source/lecture SORT Создана DESC --> <!-- QueryToSerialize: LIST FROM #type/source/lecture SORT Создана DESC -->
<!-- SerializedQuery: LIST FROM #type/source/lecture SORT Создана DESC --> <!-- SerializedQuery: LIST FROM #type/source/lecture SORT Создана DESC -->
- [[Доклад. Могут ли Virtual threads заменить Webflux]] - [[Доклад. Могут ли Virtual threads заменить Webflux]]
- [[Доклад]] - [[Доклад]]
- [[Доклад. Индексы в PostgreSQL. Как понять, что создавать]]
<!-- SerializedQuery END --> <!-- SerializedQuery END -->
## Статьи ## Статьи
<!-- QueryToSerialize: LIST FROM #type/source/article SORT Создана DESC --> <!-- QueryToSerialize: LIST FROM #type/source/article SORT Создана DESC -->