Оптимизация обращений к базе данных

При разборе времени генерации ответа от сервера иногда узким местом может быть обращение к СУБД. Оптимизацию времени доступа к СУБД можно разделить на несколько видов:

Использование параметризованных запросов

Некоторые программисты совершают ошибку, вписывая параметры (например, идентификаторы) запроса сразу в запрос. Первым шагом СУБД пытается проанализировать запрос. Если параметры приходят в запросе, в кеш запрос не складывается. Но если параметры прикладывать к запросу, структура запроса не меняется. Значит, при следующем запросе, есть вероятность нахождения проанализированной структуры в кеше, что позволит ускорить выполнение.

Размещение приложения “ближе” к СУБД

Улучшение сетевой связности может положительно сказаться на производительности приложения в целом, при этом вам не обязательно вносить изменения в код.

Использование постоянных соединений

Обычно поднятие соединений занимает значительное количество ресурсов СУБД. Для исполнения одних и тех же запросов не обязательно поднимать каждый раз новое соединение, можно переиспользовать. Например, в php это можно сделать одним атрибутом соединения https://www.php.net/manual/ru/features.persistent-connections.php

Написание хранимых процедур

Порог входа для написания хранимых процедур достаточно высок. Но если проект высоко нагружен и все остальные способы оптимизации вы уже перебрали, стоит попробовать.

Несколько запросов, зависящих друг от друга, можно объединить таким способом и снизить затраты на сетевой обмен между сервером приложений и сервером баз данных.

Оптимизация запросов и расстановка индексов

Здесь подразумевается использование инструментов MySQL SLOW LOG, explain.

Убираем лишние таблицы / данные из запросов

Стоит свежим взглядом осмотреть запросы не предмет неиспользуемых таблиц/полей в запросах. Это может дать значительный эффект в проект, в который частно вносятся изменения, но при этом рефакторинга “на свежую голову” давно не было.

Расстановка индексов

Индексы добавляют размера базе данных, но позволяют ускорить запросы. Стоит поискать баланс с помощью EXPLAIN.

Денормализация и объединение запросов

Этот вариант требует значительных затрат и модификации. В большинстве систем данные нормализованы для поддержания целостности. Но с точки зрения оптимизации времени выборка из одной таблицы обходится дешевле, чем связка нескольких и выборка из связки.

Поиск аномалий

Иногда стоит взглянуть на полный лог SQL-запросов, чтобы понять действительное положение вещей. Может казаться, что узкое место - одно, а на самом деле - другое (например, приложение генерит много UPDATE, хотя не должно). В случае с docker-compose можно сделать так:

version: '2.3'
services:
    mysql:
        image: 'percona:8.0'
        command:
            - --general-log=1
            - --general-log-file=/tmp/general.log

Далее просмотреть содержимое файла /tmp/general.log.