Навигация
- 3.1 Общие положения оптимизации на уровне базы данных
- 3.2 Оптимизация структуры базы данных
- 3.3 Эффективное построение SQL-запросов
- 3.4 Оптимизация доступа к данным
3.1 Общие положения оптимизации на уровне базы данных
База данных является важной частью веб-приложения. Сегодня сложно представить веб-приложение, которое не использовало бы базу данных. Базы данных часто используют даже одностраничные сайты (SPA), например, для хранения отзывов пользователей. При этом именно производительность базы данных нередко становится одним из ключевых элементов, определяющих быстродействие всей системы. Современные базы данных предоставляют инженеру программного обеспечения широкий набор инструментов для оптимизации производительности.
Хорошо оптимизированного кода (как на серверной, так и на клиентской сторонах приложения), использования возможностей фреймворка Yii2 (в части оптимизации), а также хорошо оптимизированной инфраструктуры часто оказывается недостаточно для обеспечения высокой производительности приложения. Это может быть связано с тем, что неэффективные запросы или неправильная структура базы данных способны привести к существенному замедлению работы всей системы, особенно при увеличении посещаемости приложения. В таком случае усилия по оптимизации на других уровнях могут быть сведены к минимуму. По этой причине оптимизация производительности базы данных является важной составной частью общей системы оптимизации производительности веб-приложения, разработанного на PHP с использованием фреймворка Yii2.
Согласно результатам опроса разработчиков, который был проведен в рамках проекта Stack Overflow в 2025 году, наиболее популярной базой данных является PostgreSQL, второе по популярности место занимает MySQL1. Подробный график наиболее распространенных по мнению разработчиков баз данных в мире представлен на рисунке 4.

Рисунок 4 ¾ Результаты опроса разработчиков 2025 года об использовании баз данных2
Однако именно MySQL традиционно исторически входит в состав наиболее распространенных наборов технологий для разработки приложений на PHP. Сначала для обозначения такого набора технологий использовался акроним LAMP (Linux, Apache, MySQL, PHP), а потом LEMP (Linux, Nginx, MySQL, PHP) после того, как Nginx получил более широкое распространение по сравнению с Apache.
Согласно официальной документации по Yii2, указанный фреймворк нативно поддерживает следующие базы данных: MySQL; MariaDB; SQLite; PostgreSQL (версии 8.4 и выше); CUBRID (версии 9.3 или выше); Oracle; MSSQL (версии 2008 или выше)3. Несмотря на то, что фреймворк Yii2 поддерживает обе наиболее распространенные базы данных, разработчики на PHP часто выбирают MySQL. В рамках настоящей работы будут рассмотрены наиболее распространенные способы оптимизации MySQL, с использованием фреймворка Yii2.
MySQL предусматривает широкие возможности в части оптимизации производительности. В литературе подробно рассматривается множество способов оптимизации производительности MySQL, в числе которых можно отметить следующие: оптимизация схемы и индексирование; оптимизация запросов; оптимизация параметров сервера; оптимизация операционной системы и оборудования; репликация; масштабирование и высокая доступность; оптимизация на уровне приложения4.
В приложениях, разработанных с использованием фреймворка Yii2, взаимодействие с базой данных осуществляется преимущественно через класс Active Record. В общем виде Active Record представляет собой объект, выполняющий роль оболочки для строки таблицы или представления базы данных. Он инкапсулирует доступ к базе данных и добавляет к данным логику домена5. При разработке приложений с использованием фреймворка Yii2, Active Record используется в качестве ORM и представляет собой способ манипулирования данными. Поэтому оптимизация производительности приложения, разработанного с использованием фреймворка Yii2 на уровне базы данных, должна учитывать как особенности MySQL, так и специфику работы ORM фреймворка.
В данной главе ВКР рассмотрим основные методики оптимизации производительности веб-приложений на уровне базы данных MySQL. Соответствующие методики предлагается классифицировать на три группы: 1) оптимизация структуры базы данных (особенности проектирования баз данных); 2) эффективное построение SQL-запросов и индексирование; 3) оптимизация доступа к данным (главным образом, в части минимизации количества обращений к базе данных).
3.2 Оптимизация структуры базы данных
В литературе отмечается, что оптимизация неправильно спроектированной схемы может существенно повысить производительность веб-приложения. Разработка схемы таблиц и установка индексов осуществляется под конкретные запросы, которые будут выполняться. Кроме того, следует определить требования к производительности для различных типов запросов, поскольку изменения в одном из них или в одной части схемы могут иметь последствия в других местах. По этой причине оптимизация производительности часто требует компромиссов. Например, добавление индексов для ускорения выборки данных (SELECT) замедляет их изменение (UPDATE). Аналогично денормализованная схема ускоряет некоторые типы запросов, но замедляет другие. Добавление таблиц счетчиков (таблицы или поля, в которых хранятся уже посчитанные значения) и сводных таблиц (таблицы, в которых хранятся агрегированные (обобщенные) данные, полученные из других таблиц) являются хорошими способами оптимизации запросов, но их поддержка может потребовать большого количества времени инженеров в области программного обеспечения6.
Одним из способов оптимизации структуры базы данных является обоснованный выбор типов данных. Использование типов данных необходимого размера позволяет сократить объем хранимой информации и повысить скорость выполнения запросов. Например, применение типа INT (каждое значение занимает 4 байта) вместо BIGINT (каждое значение занимает 8 байт) при отсутствии необходимости хранения больших числовых значений позволяет уменьшить размер таблиц и повысить эффективность обработки данных.
Аналогично использование VARCHAR с ограниченной длиной является более эффективным по сравнению с применением текстовых типов (например, TEXT) большого объема. Также в качестве методики оптимизации производительности можно отметить использование атрибута UNSIGNED для числовых полей, в которых не предполагаются отрицательные значения (например, идентификаторы или счетчики могут храниться как INT UNSIGNED). Это позволит увеличить диапазон положительных значений без увеличения размера типа данных и будет способствовать более эффективному хранению и обработке данных.
При проектировании структуры базы данных необходимо учитывать особенности хранения строковых и числовых данных. Чрезмерное использование строковых полей увеличивает объем таблиц и снижает эффективность обработки информации. Для хранения фиксированных значений в литературе рекомендуется использовать перечисления (ENUM) либо числовые идентификаторы, связанные со справочными таблицами7.
Важной методикой оптимизации структуры базы данных является нормализация. Нормализация позволяет устранить дублирование и обеспечить целостность данных путем разделения информации на взаимосвязанные таблицы. Такой подход позволяет уменьшить объем хранимых данных и упростить поддержку структуры базы данных (например, индексы будут добавляться быстрее).
Однако при разработке высоконагруженных систем может применяться денормализация базы данных. Данный подход предполагает частичное дублирование данных с целью сокращения количества операций соединения таблиц и ускорения чтения информации. Денормализация позволяет повысить производительность отдельных операций, однако усложняет поддержку актуальности данных и может увеличивать объем хранимой информации.
Существенное влияние на производительность базы данных оказывает структура первичных (PRIMARY KEY) и внешних (FOREIGN KEY) ключей. Обоснованное использование коротких числовых первичных ключей (например, TINYINT, SMALLINT, MEDIUMINT, INT) позволяет уменьшить размер таблиц и повысить эффективность хранения данных и доступа к данным. В качестве первичных ключей рекомендуется использовать автоинкрементные целочисленные значения, поскольку они обеспечивают более рациональную организацию данных в MySQL (например, каждое значение INT потребует 4 байта, тогда как UUID в строке около 36 байт).
В литературе также рекомендуется избегать использования NULL при определении столбцов. Соответствующая рекомендация объясняется тем, что столбец, допускающий NULL, занимает больше места на диске и требует специальной обработки внутри MySQL. Когда такой столбец проиндексирован, ему требуется дополнительный байт для каждой записи8.
Использование индексов также следует рассматривать в качестве методики оптимизации структуры базы данных. Индексы позволяют ускорить поиск и обработку данных, однако их применение должно быть обоснованным, поскольку избыточное количество индексов увеличивает объем хранимой информации и усложняет операции изменения данных. Особенности индексирования и воздействие индексов на выполнение SQL-запросов рассматриваются в разделе 3.3 настоящей ВКР.
Оптимизация структуры базы данных включает обоснованное определение типов данных, проектирование таблиц, корректное использование нормализации и денормализации, а также уместную установку ключей и индексов. Комплексное применение данных подходов позволит повысить производительность веб-приложения и обеспечить эффективную работу системы при увеличении объема данных и количества пользователей.
3.3 Эффективное построение SQL-запросов
Одним из основных правил оптимизации в части эффективного построения SQL-запросов является выбор только необходимых полей вместо использования конструкции SELECT *. Получение избыточных данных увеличивает объем передаваемой информации и замедляет выполнение запросов. Также в литературе рекомендуется ограничивать количество возвращаемых строк при помощи оператора LIMIT, что позволяет снизить нагрузку на сервер базы данных при обработке больших объемов данных9.
Наличие неоптимизированных запросов может приводить к полному сканированию таблиц, а также необоснованно высокому потреблению ресурсов. Основные рекомендации по построению эффективных SQL-запросов заключаются в следующем. Необходимо выбирать только необходимые поля вместо использования SELECT *, ограничивать количество возвращаемых строк с помощью LIMIT, избегать вложенных подзапросов при возможности использования JOIN, использовать фильтрацию на стороне базы данных (а не в приложении), избегать функций над индексируемыми полями в условиях WHERE. Пример неоптимального запроса: SELECT * FROM orders;. Оптимизированный вариант запроса: SELECT id, created_at, status FROM orders WHERE status = 'active' LIMIT 100;
Для повышения эффективности запросов рекомендуется использовать операции JOIN вместо большого количества вложенных подзапросов. Объединение таблиц позволяет получать связанные данные в рамках одного запроса и позволяет обеспечить более эффективную обработку данных. Кроме того, важным элементом оптимизации является использование фильтрации данных на стороне базы данных с применением условий WHERE.
Существенное воздействие на производительность базы данных оказывает применение индексов. Индексы позволяют ускорить поиск данных (без полного сканирования). Это особенно актуально для больших таблиц. В литературе выделяют следующие типы индексов: первичный ключ (PRIMARY KEY); уникальный индекс (UNIQUE); составной индекс (по нескольким полям); индекс по внешнему ключу10.
Индексация особенно важна для полей, используемых в условиях WHERE, в JOIN-операциях, при сортировке (ORDER BY), при группировке (GROUP BY). Пример создания индекса: CREATE INDEX idx_orders_status ON orders(status);. Важно учитывать, что избыточное количество индексов также может снижать производительность операций вставки (INSERT) и обновления (UPDATE), поэтому их использование должно быть обоснованным. Основными типами индексов являются: первичный ключ (PRIMARY KEY); уникальный индекс (UNIQUE); составной индекс; индекс по внешнему ключу. Индексирование особенно эффективно для полей, используемых: в условиях WHERE; в операциях JOIN; при сортировке ORDER BY; а также при группировке GROUP BY.
При использовании индексов необходимо учитывать, что их избыточное количество может снижать производительность операций вставки (INSERT) и обновления (UPDATE), поскольку системе требуется поддерживать актуальность каждой индексной структуры. Поэтому создание индексов должно выполняться только для полей, активно используемых в запросах. Эффективное построение SQL-запросов и корректное использование индексов позволит повысить производительность веб-приложения (на уровне базы данных), а также сократить время обработки данных и уменьшить нагрузку на сервер базы данных.
3.4 Оптимизация доступа к данным
В рамках данной темы нас главным образом интересует минимизация количества обращений к базе данных приложения. Рассмотрим только прикладной уровень доступа к данным: проблему N+1; соотношение и воздействие на производительности жадной и ленивая загрузок; кэширование; и постраничную навигацию. Основная проблема заключается в избыточном количестве обращений к базе данных. Это приводит к увеличению времени ответа приложения, повышению нагрузки на сервер и снижению общей производительности веб-приложения.
Одной из наиболее распространенных проблем является проблема N+1-запросов. Она возникает в случаях, когда приложение сначала выполняет один запрос для получения основного набора данных, а затем дополнительно выполняет отдельный запрос для каждого полученного элемента. Например, после получения списка пользователей приложение может отдельно запрашивать заказы каждого пользователя. В результате количество запросов существенно возрастает, что негативно влияет на производительность системы.
Для устранения проблемы N+1-запросов используются механизмы жадной загрузки данных (Eager Loading). Жадная загрузка позволяет заранее получать связанные сущности вместе с основным набором данных, что сокращает количество обращений к базе данных. В отличие от жадной загрузки, ленивая загрузка (Lazy Loading) загружает связанные данные только в момент обращения к ним, что при большом количестве объектов может приводить к формированию множества дополнительных запросов.
Важным методом оптимизации доступа к данным является использование кэширования. При повторных обращениях к часто используемой информации данные могут извлекаться из кэша без выполнения повторных запросов к базе данных. Это позволяет снизить нагрузку на сервер базы данных и сократить время обработки запросов. Однако применение кэширования требует контроля в части актуальности данных и организации механизмов обновления кэша.
Дополнительным способом оптимизации является ограничение объема одновременно загружаемых данных. Для этого применяется постраничный вывод данных (постраничная навигация), позволяющий получать информацию небольшими частями. Такой подход уменьшает объем передаваемых данных и снижает нагрузку на сервер при обработке пользовательских запросов. Обоснованная настройка механизмов загрузки данных позволяет повысить эффективность взаимодействия приложения с базой данных и уменьшить потребление серверных ресурсов.
Таким образом, оптимизация производительности веб-приложения в части обеспечения доступа к данным включает устранение проблемы N+1-запросов, использование механизмов жадной и ленивой загрузок, кэширования и постраничной навигации. Комплексное применение данных подходов позволит сократить количество обращений к базе данных, уменьшить нагрузку на сервер MySQL и повысить производительность веб-приложения.
Stack Overflow. Опрос разработчиков 2025 года об используемых инструментах и технологиях. [Электронный ресурс]. – URL: https://survey.stackoverflow.co/2025/technology (дата обращения: 04.03.2026). ↩
Stack Overflow. Опрос разработчиков 2025 года об используемых инструментах и технологиях. [Электронный ресурс]. – URL: https://survey.stackoverflow.co/2025/technology (дата обращения: 04.03.2026). ↩
Полное руководство по Yii 2.0. [Электронный ресурс]. – URL: https://www.yiiframework.com/doc/guide/2.0/ru/db-dao (дата обращения: 04.03.2026). ↩
Шварц Б., Зайцев П., Ткаченко В., Заводны Дж., Ленц А., Бэллинг Д. MySQL. Оптимизация производительности, 2-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2010. ↩
Фаулер М. Шаблоны корпоративных приложений. Пер. с англ. – М.: ООО «И.Д. Вильямс», 2016. ↩
Шварц Б., Зайцев П., Ткаченко В., Заводны Дж., Ленц А., Бэллинг Д. MySQL. Оптимизация производительности, 2-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2010. ↩
Шварц Б., Зайцев П., Ткаченко В., Заводны Дж., Ленц А., Бэллинг Д. MySQL. Оптимизация производительности, 2-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2010. ↩
Шварц Б., Зайцев П., Ткаченко В., Заводны Дж., Ленц А., Бэллинг Д. MySQL. Оптимизация производительности, 2-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2010. ↩
Шварц Б., Зайцев П., Ткаченко В., Заводны Дж., Ленц А., Бэллинг Д. MySQL. Оптимизация производительности, 2-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2010. ↩
Шварц Б., Зайцев П., Ткаченко В., Заводны Дж., Ленц А., Бэллинг Д. MySQL. Оптимизация производительности, 2-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2010. ↩
Coding is used in almost all aspects of life and work now, be it directly or indirectly. It’s not just for companies in the tech sector. “An increasing number of businesses rely on computer code,
Coding is used in almost all aspects of life and work now, be it directly or indirectly. It’s not just for companies in the tech sector. “An increasing number of businesses rely on computer code,
Coding is used in almost all aspects of life and work now, be it directly or indirectly. It’s not just for companies in the tech sector. “An increasing number of businesses rely on computer code,