Обновление
27
dev/database/DB page.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
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) -->
|
||||
|
@ -6,6 +6,8 @@ tags:
|
||||
- maturity/🌱
|
||||
date: 2024-10-23
|
||||
---
|
||||
![[../../../meta/files/images/Pasted image 20241104202857.png]]
|
||||
|
||||
**Особенности:**
|
||||
- Основан на работе [[../../fundamental/structure/B-tree|B-tree]] дерева.
|
||||
- Подходит для операций сравнения (`<`, `>`, `BETWEEN`), равенства (`=`) и сортировки.
|
||||
@ -27,7 +29,7 @@ CREATE INDEX idx_name ON table_name (column_name);
|
||||
**Создана**:: [[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) -->
|
||||
|
@ -13,7 +13,7 @@ parents:
|
||||
linked:
|
||||
- "[[Репликация в PostgreSQL]]"
|
||||
---
|
||||
В журнал попадают физические изменения, т.е. обновления страничек. Есть [[../../fundamental/Страница|страница]] в памяти, на ней лежат какие-то данные, мы с ней что-то сделали – вот эту разницу мы записываем в журнал.
|
||||
В журнал попадают физические изменения, т.е. обновления страничек. Есть [[../DB page|страница]] в памяти, на ней лежат какие-то данные, мы с ней что-то сделали – вот эту разницу мы записываем в журнал.
|
||||
|
||||
В WAL попадает всё: обновление таблиц, создание триггеров, создание хранимых процедур и так далее.
|
||||
|
||||
|
@ -12,7 +12,7 @@ date: 2024-03-31
|
||||
- **Распухание индексов** (bloat) — это проблема увеличения размера индексов со временем, требующая переиндексации.
|
||||
|
||||
- [[Создание индекса в PostgreSQL]]
|
||||
- [[../Частичный индекс]]
|
||||
- [[../Частичный индекс|Частичный индекс]]
|
||||
- [[Составной индекс в PostgreSQL]]
|
||||
|
||||
**Типы индексов:**
|
||||
@ -22,6 +22,10 @@ date: 2024-03-31
|
||||
- [[SP-GiST индекс в PostgreSQL|SP-GiST индекс]]
|
||||
- [[GIN индекс в PostgreSQL|GIN индекс]]
|
||||
- [[BRIN индекс в PostgreSQL|BRIN индекс]]
|
||||
|
||||
**Влияние обновления строки на индекс**
|
||||
- **Обновление индексированной колонки.** По факту мы добавляем новую запись в индекс, а старую забываем. Старая остается мертвым грузом (bloat), индекс распухает, его нужно убрать vacuum.
|
||||
- **Обновление не индексированной колонки.** Если строка в таблице остается на той же [[../DB page|странице бд]], то есть было место на странице, то индекс не меняется. Если строка не помещается, то добавляется новая запись в индекс, а старая остается мертвым грузом (bloat), индекс распухает, его нужно убрать vacuum.
|
||||
***
|
||||
## Мета информация
|
||||
**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]
|
||||
|
@ -26,13 +26,15 @@ EXPLAIN (FORMAT JSON) SELECT * FROM users WHERE id = 20;
|
||||
> [!NOTE] Analyze
|
||||
> `EXPLAIN` не выполняет сам запрос, поэтому результаты будут приблизительными. Для более точного анализа можно добавить ключевое слово `ANALYZE`, и тогда `EXPLAIN` также выполнит запрос.
|
||||
## Стоимость выполнения запроса (cost)
|
||||
PostgreSQL использует условные единицы для обозначения стоимости выполнения запроса — `cost`. Один `cost` примерно соответствует времени, затраченному на извлечение одного блока данных размером 8 килобайт при последовательном сканировании (Seq Scan).
|
||||
PostgreSQL использует условные единицы для обозначения стоимости выполнения запроса — `cost`. Один `cost` примерно соответствует времени, затраченному на извлечение одной [[../DB page|страницы]] при последовательном сканировании (Seq Scan).
|
||||
|
||||
Часто используются два значения `cost`:
|
||||
- **Первое значение**: стоимость до начала получения первых результатов.
|
||||
- **Второе значение**: полная стоимость выполнения запроса.
|
||||
|
||||
Если оценочное значение `rows` слишком низкое по сравнению с фактическим количеством строк, это может означать, что статистика таблицы устарела. В таком случае необходимо выполнить `ANALYZE` для обновления статистики и улучшения качества планирования запросов.
|
||||
|
||||
Также PostgreSQL умеет считать количество обращений к диску. Для этого нужно добавить опцию `buffres`: `explain (analize, buffres)`. Это не время на чтение.
|
||||
## Виды проходов по таблице и индексу
|
||||
- **Seq Scan**: последовательный просмотр всей таблицы. Это наиболее медленный вариант и обычно нежелателен. Решение — добавить [[../Индекс базы данных|индекс]], чтобы ускорить выборку данных.
|
||||
- **Index Scan**: использование [[../Индекс базы данных|индекса]] для просмотра таблицы.
|
||||
|
@ -5,7 +5,7 @@ tags:
|
||||
date: 2024-03-31
|
||||
linked:
|
||||
---
|
||||
[[../Составные индексы в БД|Составные индексы]] в PostgreSQL позволяют ускорить выполнение запросов, в которых используются несколько колонок одновременно. Однако важно учитывать особенности их частичного использования.
|
||||
[[../Составной индекс в БД|Составные индексы]] в PostgreSQL позволяют ускорить выполнение запросов, в которых используются несколько колонок одновременно. Однако важно учитывать особенности их частичного использования.
|
||||
|
||||
При выполнении запроса составной индекс может использоваться до первого неравенства включительно. Это означает, что при встрече оператора неравенства (`>`, `<`, `>=`, `<=`) индекс перестает быть эффективным для последующих колонок.
|
||||
|
||||
@ -17,7 +17,7 @@ linked:
|
||||
***
|
||||
## Мета информация
|
||||
**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]
|
||||
**Родитель**:: [[../Составные индексы в БД|Составные индексы в БД]], [[Индекс в PostgreSQL]]
|
||||
**Родитель**:: [[../Составной индекс в БД|Составной индекс в БД]], [[Индекс в PostgreSQL]]
|
||||
**Источник**::
|
||||
**Автор**::
|
||||
**Создана**::
|
||||
|
24
dev/database/postgresql/Таблица в PostgreSQL.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
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) -->
|
||||
|
@ -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) -->
|
||||
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||||
- [[Индекс в PostgreSQL]]
|
||||
- [[Индекс в MySQL]]
|
||||
- [[Составные индексы в БД]]
|
||||
- [[Индекс в PostgreSQL]]
|
||||
- [[Покрывающий индекс]]
|
||||
- [[Составной индекс в БД]]
|
||||
<!-- SerializedQuery END -->
|
||||
|
||||
|
30
dev/database/Индекс в БД для мягкого удаления.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
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) -->
|
||||
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
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) -->
|
||||
|
@ -1,18 +1,17 @@
|
||||
---
|
||||
aliases:
|
||||
- Составные индексы
|
||||
- многоколоночный индекс
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date: 2024-06-16
|
||||
---
|
||||
Составным называется индекс, который включает в себя сразу несколько полей. Он используется для повышения производительности запросов, которые фильтруют данные по нескольким колонкам одновременно.
|
||||
Составной индекс — это индекс, включающий несколько полей, который используется для повышения производительности запросов, фильтрующих данные сразу по нескольким колонкам.
|
||||
|
||||
==В составных индексах важен порядок столбцов.== Порядок колонок в индексе влияет на его эффективность, и более [[Селективность колонки|селективные]] поля должны идти первыми, чтобы максимизировать производительность. SQL-запросы также должны следовать этому порядку для оптимального использования индекса.
|
||||
Проще всего представить составной индекс не как последовательность индексов по отдельным колонкам, а как индекс по объединённым значениям этих колонок. Поэтому порядок столбцов в составном индексе имеет значение.== Он влияет на эффективность индекса, и поэтому чаще всего ==наиболее [[Селективность колонки|селективные]] поля следует располагать первыми== для максимальной производительности. ==SQL-запросы также должны учитывать этот порядок== для оптимального использования индекса.
|
||||
|
||||
При поиске по составному индексу значения колонок сравниваются по порядку, что делает порядок следования колонок критически важным для эффективности запросов.
|
||||
|
||||
> [!WARNING] Количество параметров
|
||||
> Составной индекс из 2-3 полей обычно считается нормальным и эффективно поддерживаемым. Если количество колонок в индексе превышает три, следует тщательно анализировать его использование, чтобы избежать излишней нагрузки на производительность.
|
||||
Однако, есть исключительные ситуации из этого правила:
|
||||
- [[Использование малоселективных полей для оптимизации чтения страниц]]
|
||||
|
||||
**Преимущества:**
|
||||
- **Оптимизация дискового пространства**: ==Один составной индекс может заменить несколько простых индексов==, что экономит дисковое пространство.
|
||||
@ -22,6 +21,12 @@ date: 2024-06-16
|
||||
- **Высокие накладные расходы при обновлении**: Каждый раз при вставке, обновлении или удалении данных, которые попадают в составной индекс, СУБД должна обновлять весь индекс, что может увеличивать время выполнения таких операций.
|
||||
- Старайтесь минимизировать использование неравенств в начале составных индексов, так как это может ограничить их применение для последующих колонок.
|
||||
|
||||
> [!WARNING] Количество параметров
|
||||
> Составной индекс из 2-3 полей обычно считается нормальным и эффективно поддерживаемым. Если количество колонок в индексе превышает три, следует тщательно анализировать его использование, чтобы избежать излишней нагрузки на производительность.
|
||||
|
||||
|
||||
|
||||
|
||||
Создание составного индекса:
|
||||
```sql
|
||||
CREATE INDEX idx_example ON table_name (column_a, column_b);
|
44
dev/database/Таблицы с колонкой статуса.md
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
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) -->
|
||||
|
@ -26,46 +26,8 @@ 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]]
|
||||
|
@ -12,9 +12,10 @@ date: 2024-01-29
|
||||
- Узел содержит множество элементов, что позволяет хранить больше данных в одном месте.
|
||||
- Каждый узел представляет собой [[../Страница|страничку]] на диске, что снижает издержки на чтение.
|
||||
- В каждом узле есть ссылки на следующий и предыдущий узлы (характерно для B+tree).
|
||||
- В узлах дерева могут храниться сами данные или указатели на данные.
|
||||
- В листьях дерева могут храниться сами данные или указатели на данные, то есть ссылаются на таблицу.
|
||||
- Элементы в узле отсортированы, что делает поиск более эффективным и позволяет создавать деревья с небольшой высотой, тем самым уменьшая количество обращений к диску.
|
||||
- Значения в узлах могут быть не уникальными.
|
||||
- Обычно высота дерева не больше 3-4 уровней.
|
||||
## Параметр t
|
||||
Параметр `t` определяет количество элементов в узле дерева.
|
||||
- В каждом узле должно быть не менее `t-1` и не более `2t-1` ключей. Это правило важно для поддержания сбалансированности дерева, так как позволяет равномерно распределять элементы между узлами и поддерживать эффективную высоту дерева, что, в свою очередь, обеспечивает высокую производительность операций поиска.
|
||||
@ -31,13 +32,23 @@ date: 2024-01-29
|
||||
- Поиск четных или нечетных чисел.
|
||||
- Поиск суффиксов (`LIKE '%c'` — неэффективно).
|
||||
## Поиск в B-tree
|
||||
Рассмотрим пример поиска значения `27`.
|
||||
|
||||
![](../../../meta/files/images/Pasted%20image%2020240129193115.png)
|
||||
|
||||
Значения в узлах могут быть не уникальными. Например, если значение `27` встречается дважды, поиск продолжается, переходя в следующий узел. Чтобы облегчить этот процесс, блоки на одном уровне связаны, создавая связный список.
|
||||
|
||||
Алгоритм поиска аналогичен [[Бинарное дерево поиска|бинарному дереву]], но выбор осуществляется из нескольких вариантов, а не из двух. Поиск выполняется за `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
|
||||
Представим, что нужно вставить значение `15` в уже существующее дерево.
|
||||
|
||||
|
@ -3,12 +3,11 @@ aliases:
|
||||
- страницы
|
||||
- страниц
|
||||
- страничку
|
||||
- страницы ОС
|
||||
- Страница ОС
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date: 2024-09-17
|
||||
zero-link:
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
Страница это непрерывный блок памяти фиксированного размера.
|
||||
|
||||
@ -39,3 +38,6 @@ linked:
|
||||
|
||||
### Дочерние заметки
|
||||
<!-- 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 -->
|
||||
|
@ -0,0 +1,37 @@
|
||||
---
|
||||
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) -->
|
||||
|
23
dev/Посмотренные доклады по разработке.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
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) -->
|
||||
|
BIN
meta/files/images/Pasted image 20241104202857.png
Normal file
After Width: | Height: | Size: 614 KiB |
BIN
meta/files/images/Pasted image 20241104203100.png
Normal file
After Width: | Height: | Size: 601 KiB |
BIN
meta/files/images/Pasted image 20241104203423.png
Normal file
After Width: | Height: | Size: 637 KiB |
BIN
meta/files/images/Pasted image 20241104203446.png
Normal file
After Width: | Height: | Size: 668 KiB |
BIN
meta/files/images/Pasted image 20241104203517.png
Normal file
After Width: | Height: | Size: 716 KiB |
BIN
meta/files/images/Pasted image 20241104204304.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
meta/files/images/Pasted image 20241105002717.png
Normal file
After Width: | Height: | Size: 810 KiB |
BIN
meta/files/images/comp/Pasted image 20241104202857.png
Normal file
After Width: | Height: | Size: 130 KiB |
@ -0,0 +1 @@
|
||||
f7acfd614fc477ebff10b74de2d716ed
|
BIN
meta/files/images/comp/Pasted image 20241104203100.png
Normal file
After Width: | Height: | Size: 121 KiB |
@ -0,0 +1 @@
|
||||
933b38087b1601e6864908001b041df5
|
BIN
meta/files/images/comp/Pasted image 20241104203423.png
Normal file
After Width: | Height: | Size: 129 KiB |
@ -0,0 +1 @@
|
||||
e82618e260f128c6cd048561af961e44
|
BIN
meta/files/images/comp/Pasted image 20241104203446.png
Normal file
After Width: | Height: | Size: 134 KiB |
@ -0,0 +1 @@
|
||||
611a31d49324aab65ef65af0d5710ad7
|
BIN
meta/files/images/comp/Pasted image 20241104203517.png
Normal file
After Width: | Height: | Size: 141 KiB |
@ -0,0 +1 @@
|
||||
bf46eb6f9a60ee2907f1030ceb9ce2cf
|
BIN
meta/files/images/comp/Pasted image 20241104204304.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1 @@
|
||||
035fd400699ca217a05fbe1e517d12a8
|
BIN
meta/files/images/comp/Pasted image 20241105002717.png
Normal file
After Width: | Height: | Size: 207 KiB |
@ -0,0 +1 @@
|
||||
b46e120ce165d4f7a8ea5df8c60a4d31
|
BIN
meta/files/images/webp/Pasted image 20241104202857.webp
Normal file
After Width: | Height: | Size: 67 KiB |
@ -0,0 +1 @@
|
||||
f7acfd614fc477ebff10b74de2d716ed
|
BIN
meta/files/images/webp/Pasted image 20241104203100.webp
Normal file
After Width: | Height: | Size: 70 KiB |
@ -0,0 +1 @@
|
||||
933b38087b1601e6864908001b041df5
|
BIN
meta/files/images/webp/Pasted image 20241104203423.webp
Normal file
After Width: | Height: | Size: 73 KiB |
@ -0,0 +1 @@
|
||||
e82618e260f128c6cd048561af961e44
|
BIN
meta/files/images/webp/Pasted image 20241104203446.webp
Normal file
After Width: | Height: | Size: 74 KiB |
@ -0,0 +1 @@
|
||||
611a31d49324aab65ef65af0d5710ad7
|
BIN
meta/files/images/webp/Pasted image 20241104203517.webp
Normal file
After Width: | Height: | Size: 80 KiB |
@ -0,0 +1 @@
|
||||
bf46eb6f9a60ee2907f1030ceb9ce2cf
|
@ -0,0 +1 @@
|
||||
035fd400699ca217a05fbe1e517d12a8
|
BIN
meta/files/images/webp/Pasted image 20241105002717.webp
Normal file
After Width: | Height: | Size: 102 KiB |
@ -0,0 +1 @@
|
||||
b46e120ce165d4f7a8ea5df8c60a4d31
|
@ -19,6 +19,7 @@ title: PostgreSQL
|
||||
- Изменение данных не заменяет строчку физически в памяти, а добавляет новую версию строки. Устаревшие строки через какое-то время помечаются и в них пишутся новые данные.
|
||||
- Если транзакции нужно выполнить операцию с данными, с которыми работает другая транзакция, то она может встать в очередь.
|
||||
- В логи попадают не все запросы. Это настраивается конфигурационными параметрами. Если логировать все запросы, то просядет производительность.
|
||||
- Типичный размер [[../../dev/database/DB page|страницы]] 8 килобайт. На страницу помещается ~ 100 записей.
|
||||
|
||||
## Дополнительные материалы
|
||||
- [pg_utils](../../dev/database/postgresql/pg_utils.md)
|
@ -35,7 +35,7 @@ linked:
|
||||
|
||||
## Заметки
|
||||
- Классические СУБД хранят данные в двух местах: на диске и в памяти.
|
||||
- [[../../dev/fundamental/Страница|Страница]] модифицируется сначала в оперативной памяти, потом попадает на диск.
|
||||
- [[../../dev/database/DB page|Страница БД]] модифицируется сначала в оперативной памяти, потом попадает на диск.
|
||||
- ![](Pasted%20image%2020240531082744.png)
|
||||
- Часто думают, что реляционная таблица — это массив. Некоторые даже думают, что это двумерный массив. На самом деле, это гораздо более сложная штука. Это мультимножество – набор определенного сорта кортежей, над которым не задано порядка. В SQL-таблице нет порядка. Это важно. И, как результат, когда вы делаете SELECT* из БД (просканировать все записи), результат выполнения запроса может меняться – строчки могут быть в одном порядке, а могут и в другом. Про это нужно помнить.
|
||||
- Профиль нагрузки на реляционную базу данных выглядит следующим образом: 80% запросов это чтение, 20% запросов это запись. Если запросов на запись больше, то возможно реляционная база данных вам не подходит.
|
||||
|
@ -4,11 +4,15 @@ tags:
|
||||
date: 2024-10-02
|
||||
---
|
||||
Здесь собраны ссылки на заметки, в которых я анализирую прочитанный/просмотренный материал.
|
||||
|
||||
- [[../dev/Посмотренные доклады по разработке|Посмотренные доклады по разработке]]
|
||||
-
|
||||
## Доклады
|
||||
<!-- QueryToSerialize: LIST FROM #type/source/lecture SORT Создана DESC -->
|
||||
<!-- SerializedQuery: LIST FROM #type/source/lecture SORT Создана DESC -->
|
||||
- [[Доклад. Могут ли Virtual threads заменить Webflux]]
|
||||
- [[Доклад]]
|
||||
- [[Доклад. Индексы в PostgreSQL. Как понять, что создавать]]
|
||||
<!-- SerializedQuery END -->
|
||||
## Статьи
|
||||
<!-- QueryToSerialize: LIST FROM #type/source/article SORT Создана DESC -->
|
||||
|