0Pricing
PHP Academy · Урок

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

Находите запросы N+1, добавляйте индексы и сокращайте количество запросов

«Оптимизация запросов к базе данных» — бесплатный урок PHP Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения PHP Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс PHP Academy содержит 4 уроков всего.

Поиск медленных запросов

Включите журнал медленных запросов MySQL и задайте порог. Проверяйте запросы, выполнение которых занимает больше ожидаемого времени.

# my.cnf:
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 0.5  # log queries over 500ms

EXPLAIN и EXPLAIN ANALYZE

Используйте EXPLAIN, чтобы понять, как MySQL выполняет запрос и используются ли индексы.

-- Run in MySQL:
EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = "pending";
-- Look for: type=ALL (full scan), key=NULL (no index used)

Добавление индексов

Индексы значительно ускоряют чтение по столбцам, используемым для фильтрации и сортировки.

-- Add composite index for the query above:
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);

// In Laravel migration:
$table->index(["user_id", "status"]);

Проблема запросов N+1

Проблема N+1 возникает, когда один запрос получает список, а затем для каждого элемента выполняется ещё один запрос для связи. Исправьте это с помощью жадной загрузки.

<?php
// BAD: 1 + N queries
$posts = Post::all();
foreach ($posts as $post) echo $post->author->name;

// GOOD: 2 queries
$posts = Post::with("author")->get();
foreach ($posts as $post) echo $post->author->name;

Выбирайте только нужные столбцы

Избегайте SELECT * — получайте только нужные столбцы, чтобы уменьшить использование памяти и объём сетевой передачи.

<?php
// Bad:
$users = User::all();

// Good:
$users = User::select("id", "name", "email")->get();

Разбиение больших наборов данных на части

Обрабатывайте большие наборы результатов частями, чтобы избежать исчерпания памяти.

<?php
User::chunk(500, function ($users) {
    foreach ($users as $user) {
        // process each user
    }
});

// Or lazy loading (PHP generator):
User::lazy()->each(fn($user) => processUser($user));

Кэширование запросов

Кэшируйте ресурсоёмкие агрегаты и отчёты, которые меняются нечасто.

<?php
$revenue = Cache::remember("monthly-revenue", 3600, function () {
    return Order::whereMonth("created_at", now()->month)->sum("total");
});

Избегайте запросов в циклах

Никогда не выполняйте запросы внутри циклов перебора. Сначала соберите идентификаторы, затем получите данные одним запросом.

<?php
// Collect all product IDs:
$ids = array_column($cartItems, "product_id");
// One query:
$products = Product::whereIn("id", $ids)->get()->keyBy("id");

foreach ($cartItems as $item) {
    $product = $products[$item["product_id"]];
}

Пул соединений с базой данных

PHP-FPM создаёт новое соединение PDO для каждого рабочего процесса. PgBouncer или ProxySQL могут объединять соединения в пул, предотвращая перегрузку базы данных из-за накладных расходов на их создание.

Покрывающие индексы

Покрывающий индекс содержит все столбцы, необходимые для выполнения запроса, поэтому MySQL может ответить на запрос только по индексу, не обращаясь к строкам основной таблицы.

Итоги

Включайте журналы медленных запросов. Используйте EXPLAIN для поиска отсутствующих индексов. Загружайте связи заранее. Выбирайте только нужные столбцы. Разбивайте большие наборы данных на части. Кэшируйте ресурсоёмкие агрегаты. Избегайте запросов внутри циклов.

Быстрая проверка

В чём заключается проблема запросов N+1?

Часто задаваемые вопросы

Урок «Оптимизация запросов к базе данных» бесплатный?

Да — полный текст урока «Оптимизация запросов к базе данных» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс PHP Academy, подпишись на CoddyKit PRO. Курс PHP Academy содержит 4 уроков всего.

Чему я научусь в уроке «Оптимизация запросов к базе данных»?

Находите запросы N+1, добавляйте индексы и сокращайте количество запросов Ты практикуешь PHP Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать PHP Academy?

Предыдущий опыт не требуется. PHP Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Оптимизация запросов к базе данных»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке PHP Academy?

Да. Каждый урок PHP Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Профилирование PHP с Xdebug
  2. OPcache: кэширование байткода
  3. Оптимизация запросов к базе данных
  4. Управление памятью и советы по производительности
← Назад к PHP Academy