Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
SlashLight authored Dec 24, 2024
1 parent fd65fdd commit e6bd279
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions perf_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Введение
Наш проект представляет из себя социальную сеть. На мой взгляд ключевой сущностью социальной сети являются пользователи,
так как помимо частых изменений таблицы с пользователями, вызванных появлением новых пользователей и изменением аккаунтов
старыми пользователями, часто появляется необходимость поиска пользователя по имени или id для корректного отображения
поста, комментария или чата. В связи с этим было выбрать ключевой сущностью для нагрузочного тестирования именно пользователей.

# Основная часть
Для начала был сделан бэкап базы при помощи pg_dump. Следом за этим были установлены инструменты для проведения
нагрузочного тестировани: wrk и vegeta. Для vegeta были написаны скрипты на Python по созданию случайных пользователей и
запросам к API для регистрации. Для wrk был написан скрипт на lua, создающий пользователя и отправляющий запрос на его
создание. К сожалению и первый и второй инструмент не только вызвали ошибки, решить которые нам не удалось, так еще и смогли
дважды превратить докер контейнер с сервисом регистрации в виртуальный кирпич, не реагирующий ни на какие команды.
В связи с этими удручающими новостями я решил предположить, как можно оптимизировать запрос на создание и поиск пользователя.
Для начала стоит сразу же отбросить идею с денормализацией, так как у таблички пользователей нет отнощений, денормализовав
которые производительность можно было бы улучшить. Значит переходим к анализу самих запросов.
Начнем с создания пользователя:
```
INSERT INTO profile (first_name, last_name, email, hashed_password)
VALUES ($1, $2, $3, $4)
ON CONFLICT (email) DO NOTHING RETURNING id;
```
На первый взгляд этот запрос не может быть улучшен. Однако, исходя из рекомендаций проведения валидации на всех возможных уровнях, нам стоит проверить,
существует ли пользователь с таким email на стороне сервера:
```
SELECT id
FROM profile
WHERE email = $1
LIMIT 1;
```
Такой запрос может быть улучшен наложением обычного btree индекса на поле email. Делать, однако, это следует только в том случае, если создание пользователя
происходит достаточно часто и становится бутылочным горлышком.

Теперь рассмотрим выборку пользователя:
```
SELECT id, first_name, last_name, bio, avatar
FROM profile
WHERE profile.id = $1
LIMIT 1;
```

Кажущийся очевидным способ ускорения этого запроса: наложения btree индекса на поле id, на самом деле не так хорош как кажется. Этот запрос действительно обладает
хорошей селективностью, но стоит обратить внимание также на другие запросы. Дело в том, что многие сущности связаны с профилем: у каждого поста,
комментария и чата должно отображаться имя пользователя и его автарка. Значит, мы можем наложить покрывающий btree индексы на id с полями first_name, last_name,
avatar, чем значительно ускорим другие запросы, в которых проводится JOIN с таблицей профилей.

# Заключение
В заключение хочется сказать, что, конечно, вышеописанные рассуждения мало чего стоят без заполнения базы данными и анализа запросов, сопровождаемых EXPLAIN`ом и
его визуализацией. Тем не менее хочется верить, что моих знаний хватило на то, чтобы правильно спрогнозировать поведение таблицы и запросов под нагрузкой, а также
написать правильные рекомендации по ускорению запросов.

0 comments on commit e6bd279

Please sign in to comment.