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 и будет быстро и хорошо. |