Очень важно идти в ногу с прогрессом и своевременно реагировать на потребности потенциальных клиентов. В современной реалии весь мир перешел в интернет, и как многие онлайн бизнесы все зависит от отклика веб приложений. Как известно, база данных является основополагающим в веб приложении, исходя от количества запросов в приложение может работать медленнее. В данной статье описывается, как лучше использовать БД MySQL в Laravel, чтобы современные веб приложения работали по принципу «швейцарских часов»
Ключевые слова: Laravel, MySQL, индекс, запрос, select, update, delete, Redis, Cache.
Скорость — критически важный фактор для долгосрочного успеха приложения. Для решения данной проблемы требуются не только мощные сервера, но также хорошо оптимизированная База Данных. Рассмотрим популярное фреймворк Laravel и базу данных MySQL. Ниже приведены советы для оптимизации базы данных.
- Предположим, имеется более миллиона записей и нужно обработать их черех цикл;
Вариант реалицации будет проходить по следующими маршруту:
$posts = DB::table(‘posts’)->get();
foreach ($posts as $post) {
//Обработка запроса
}
При данной реализации закончится запас памяти. Если вместо привычного получения записи применим chunk, то сможем решить проблему памяти путем обработки ДАННЫХ по частям, тем самым сэкономим память в приложение [2].
$posts = DB::table(‘posts’)->chunk(100, function ($posts)){
foreach($posts as $post){
//Обработка запроса
}
}
- Выбрать только нужные поля;
Рассмотрим на примере запроса:
Post::find(1);
Данный запрос возрвращает все поля и возращаемые поля весят больше, чем необходимо (или весят больше чем должны быть)
Post::select([‘id’,’title’])->find(1);
При данном запросе, возращаем нужные поля с меньшим весом (объемом) [1].
- Объединить похожие запросы;
Пример: При запросе трех разных статуса в объявлениях логично сделать запрос по нижеследующему запросу:
Post::where(‘status’,’published’)->get();
Post::where(‘status’,’featured’)->get();
Post::where(‘status’,’scheduled’)->get();
Но, в данном случае каждый отдельный запрос — это нагрузка на сервер, во избежание данной проблемы лучше применить маршрут по запросу: (применить нижеуказанный запрос:)
Post::whereIn(‘status’, [‘published’,’featured’,’scheduled’])->get();
В результате, наша задача решается одним запросом вместо трех [1].
- Добавить индекс к часто запрашиваевым полям;
Давайте рассмотрим пример использования поля status , т. к. данное поле часто применяется. В среднем если в таблице содержится более миллиона полей, то каждый запрос по полю status занимает в среднем более 10 секунд. При использовании индекс к полю status запрос будет занимать в среднем 1,2 секунды. Индекс это алгоритм бинарного поиска реализованный в MySQL [3].
- Оптимизация MySQL Insert;
В MySQL есть четыре основные операции: Insert, SELECT, Update, Delete. Из которых самым медленным является запрос Insert.
Если в основной таблице работает определенный запрос, то следующие запросы ждут выполнения предыдущего. Медленные SQL-запросы могут негативно отражаться на производительности. И для того чтобы ускорить работу Insert нужно настроить сервер.
На сервере с установленным MySQL значение innodb_log_file_size по умолчанию составляет 5 Mb. Этого бывает недостаточно для сервера с множеством запросов, поэтому нужно увеличивать параметр innodb_log_file_size до 500 Mb. Следовательно, операция Insert ускоряется.
- Тщательно выбирайте тип полей;
При сохранении текста имеется возможность несколько выбора типа полей:
VARCHAR — до 255 символов
CHAR — до 1000 символов
BLOB — не имеет огранечение.
Для рационального использования памяти, необходимо правильно использовать типы данных для целесообраного экономии БД.
Например: при хранении малых символов, нет надобности в использовании BLOB [3].
- Разделите большую таблицу на несколько частей;
Для ускорении работы имеется возможность разделении полей на несколько частей. Рассмотрим пример:
У нас имеется более 10000 записей в одной таблице вес которого составляет 4 Мб. Давайте разделим данную таблицу на несколько малых таблиц:
Первая –основная информация: ФИО, телефон, почта, пароль;
Вторая — хобби, увлечения и интересы;
Третья — дополнительные информация: контакты, семейное положение;
В результате, мы получили три таблицы с малыми объемами, исходя из этого будем легче их обработать.
- Определить тип таблиц;
В MySQL имеется два типа таблиц: InnoDB и MyISAM.
InnoDB используется для обеспечения целостности данных, таких как передача личных данных, банковские данные, транзакция банковских дел и прочие. В связи с этим InnoDB работает чуть медленнее относительно MyISAM.
Пример: если человек оплатил товар через банковскую карту, происходит процесс снятия денег с клиента и пополнения счета продавца. Таблица InnoDB будет удерживать операцию у себя в очереди, по мере окончания данного процесса.
- Используйте БД Redis;
Рассмотрим случай, если в базе работают одновременно миллион пользователей, они генерируют постоянный объем информации, что значительно тормозит работу всей базы. Это следствие того, что пока первый запрос обрабатывается, второй запрос будет стоять в очереди. Между запросами диапазон ожидания минимальный, но по мере возрастания запросов будут возникать проблемы по загруженности БД, тем самым вызывая вопросы к компетентности специалистов.
При возникновении данной проблемы необходимо использовать кэш либо временную память — Redis. Redis — это NOSQL база данных, которая используется в памяти. Redis работает немного быстрее чем MySQL, так как, Redis берет данные из памяти.
Заключение
В данной статье описаны наиболее частые ошибки. Для получения полной информации по статье вы можете дополнительно просмотреть документацию по Laravel либо использовать другие источники.
Литература:
- Официальная документация по Laravel. https://laravel.com/
- 18 tips to optimize laravel queries. https://dudi.dev/optimize-laravel-database-queries/
- MySQL. Оптимизация производительности (2020)