57 lines
4.7 KiB
Markdown
57 lines
4.7 KiB
Markdown
---
|
||
aliases:
|
||
- explain
|
||
tags:
|
||
- maturity/🌱
|
||
date: 2024-06-10
|
||
---
|
||
Ключевое слово `EXPLAIN` перед SQL-запросом позволяет получить детальную информацию о том, как PostgreSQL **планирует** выполнить этот запрос "под капотом". Это полезно для диагностики производительности, поскольку помогает понять, какие шаги выполняет база данных и где могут быть узкие места.
|
||
|
||
Пример использования `EXPLAIN`
|
||
```sql
|
||
postgres=# EXPLAIN SELECT * FROM users WHERE id = 20;
|
||
|
||
QUERY PLAN
|
||
-------------------------------------------------------
|
||
Index Scan using users_pkey on users (cost=0.15..8.17 rows=1 width=72)
|
||
Index Cond: (id = 20)
|
||
(2 rows)
|
||
```
|
||
|
||
Вывод информации можно изменить. Например, чтобы получить результат в формате JSON:
|
||
```sql
|
||
EXPLAIN (FORMAT JSON) SELECT * FROM users WHERE id = 20;
|
||
```
|
||
|
||
> [!NOTE] Analyze
|
||
> `EXPLAIN` не выполняет сам запрос, поэтому результаты будут приблизительными. Для более точного анализа можно добавить ключевое слово `ANALYZE`, и тогда `EXPLAIN` также выполнит запрос.
|
||
## Стоимость выполнения запроса (cost)
|
||
PostgreSQL использует условные единицы для обозначения стоимости выполнения запроса — `cost`. Один `cost` примерно соответствует времени, затраченному на извлечение одной [[../DB page|страницы]] при последовательном сканировании (Seq Scan).
|
||
|
||
Часто используются два значения `cost`:
|
||
- **Первое значение**: стоимость до начала получения первых результатов.
|
||
- **Второе значение**: полная стоимость выполнения запроса.
|
||
|
||
Если оценочное значение `rows` слишком низкое по сравнению с фактическим количеством строк, это может означать, что статистика таблицы устарела. В таком случае необходимо выполнить `ANALYZE` для обновления статистики и улучшения качества планирования запросов.
|
||
|
||
Также PostgreSQL умеет считать количество обращений к диску. Для этого нужно добавить опцию `buffres`: `explain (analize, buffres)`. Это не время на чтение.
|
||
## Виды проходов по таблице и индексу
|
||
- **Seq Scan**: последовательный просмотр всей таблицы. Это наиболее медленный вариант и обычно нежелателен. Решение — добавить [[../Индекс базы данных|индекс]], чтобы ускорить выборку данных.
|
||
- **Index Scan**: использование [[../Индекс базы данных|индекса]] для просмотра таблицы.
|
||
- **Index Only Scan**: использование [[../Покрывающий индекс|покрывающего индекса]], когда все нужные данные находятся в индексе и не требуется дополнительного доступа к таблице.
|
||
- **Bitmap Heap Scan**: оптимизация с использованием битовых карт для поиска. Сначала строятся битовые карты с использованием нескольких индексов, затем они комбинируются.
|
||
- **Foreign Scan**: сканирование данных на удаленном сервере, используемое при [[Шардирование в PostgreSQL|шардировании]].
|
||
|
||
***
|
||
## Мета информация
|
||
**Область**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]]
|
||
**Родитель**:: [[Оптимизация SQL запросов в PostgreSQL]]
|
||
**Источник**::
|
||
**Автор**::
|
||
**Создана**:: [[2024-01-29]]
|
||
### Дополнительные материалы
|
||
-
|
||
### Дочерние заметки
|
||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||
|