29 lines
2.1 KiB
Markdown
29 lines
2.1 KiB
Markdown
|
---
|
|||
|
aliases:
|
|||
|
tags:
|
|||
|
- зрелость/🌱
|
|||
|
date: 2024-02-05
|
|||
|
zero-link:
|
|||
|
- "[[00 SQL]]"
|
|||
|
parents:
|
|||
|
linked:
|
|||
|
---
|
|||
|
Postgres имеет три основных алгоритма Join'а, а именно
|
|||
|
- Nested Loop. Берем данные из одной таблицы и циклами их Join'им
|
|||
|
- Hash index. Одна, чаще маленькая, таблица хэшируется и по этому хэшу Join'ится с другой таблицей
|
|||
|
- Merge Join.
|
|||
|
|
|||
|
```sql
|
|||
|
SELECT * FROM posts WHERE author = "Peter"
|
|||
|
JOIN comments ON posts. id = comments.post_id
|
|||
|
```
|
|||
|
|
|||
|
Индекс по `posts.id` бесполезен. Индекс по `comments.post_id` обязателен. Если вы создадите индекс, оптимизатор выберет Nested Loop, и все будет работать быстро.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
## Почему JOIN работает медленно?
|
|||
|
- Индекс для полей по которым джойним добавлен?
|
|||
|
## Заметки
|
|||
|
- B MySQL используется метод nested loops, но с оптимизациями.
|
|||
|
- У вас оптимизатор из каких-то соображений выбирает Nested Loop, а вам кажется, что одна таблица очень маленькая, другая – очень большая и Hash Join там был бы очень уместен, потому что маленькую таблицу можно быстро прохэшировать и быстро с ней работать. Посмотрите, сколько у вас work mem'а. т.е. сколько памяти может занять один worker Postgres’а. Если эта таблица хэшируется в, например, 100 Мб, а у вас work mem'а выдано только 30 Мб, то worker будет работать медленно. Если вы добавите work mem'а и хэширование начнет вмещаться в память, оптимизатор выберет правильный Hash Join и будет быстро и хорошо.
|