Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как профилировал запросы
Профилирование запросов — это процесс анализа производительности кода и базы данных, чтобы найти узкие места.
Инструмент 1: Логирование SQL с Hibernate
spring:
jpa:
properties:
hibernate:
format_sql: true
generate_statistics: true
logging:
level:
org.hibernate.SQL: DEBUG
Это покажет все SQL запросы с временем выполнения.
Инструмент 2: JProfiler
Один из лучших профайлеров для Java. Показывает:
- CPU время по методам
- Потребление памяти
- Вызовы между методами
java -agentpath=/path/to/jprofiler/bin/libjprofilerti.so -jar myapp.jar
Инструмент 3: Java Flight Recorder
Безопасен для production, минимальный оверхед.
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder \
-XX:StartFlightRecording=filename=recording.jfr -jar myapp.jar
Инструмент 4: P6Spy для логирования SQL
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
Вывод: Показывает все SQL запросы с временем выполнения
Инструмент 5: Spring Boot Actuator
@Service
public class UserService {
@Timed(value = "user.fetch")
public User findById(Long id) {
return repository.findById(id);
}
}
Доступно по: GET /actuator/metrics/user.fetch
Инструмент 6: EXPLAIN ANALYZE в PostgreSQL
EXPLAIN ANALYZE
SELECT u.id, u.name FROM users u WHERE u.status = 'ACTIVE';
Покажет:
- Используется ли индекс
- Реальное время выполнения
- Количество прочитанных строк
Практический пример
@Service
public class ProfiledService {
@Autowired
private UserRepository repository;
public List<User> findActiveUsers() {
long start = System.currentTimeMillis();
List<User> users = repository.findByStatus(UserStatus.ACTIVE);
long elapsed = System.currentTimeMillis() - start;
logger.info("Query took {}ms", elapsed);
return users;
}
}
Инструмент 7: curl для HTTP анализа
curl -w "Total: %{time_total}ms" http://localhost:8080/api/users
Инструмент 8: Hibernate Statistics
Statistics stats = ((SessionFactoryImpl)emf).getStatistics();
stats.setStatisticsEnabled(true);
System.out.println("Entity Loads: " + stats.getEntityLoadCount());
System.out.println("Prepared Statements: " + stats.getPreparedStatementCount());
Лучшие практики профилирования
- Меряй в реалистичных условиях — с реальными данными
- Повторяй несколько раз — избегай погрешностей
- Профилируй hot spots — фокусируйся на медленных методах
- Сравнивай до/после — убедись что улучшение сработало
- Используй sampling — 100% профилирование замедляет приложение
- Ищи N+1 проблемы — частая причина медленных запросов
- Добавляй индексы — обычно дает 50% прирост
- Кэшируй результаты — для часто используемых данных
Типичные находки при профилировании
- N+1 SELECT: один запрос за каждого пользователя вместо одного
- Отсутствие индексов на часто фильтруемых полях
- Загрузка в памяти миллионов записей без пагинации
- Неправильные JOIN'ы вместо более эффективных запросов
- Кэширование для каждого запроса без TTL
Профилирование — это постоянный процесс поиска и устранения узких мест. Начинай с логирования, потом добавляй инструменты по мере необходимости.