How to Detect and Log Slow Queries in Entity Framework Core
As applications grow in complexity, performance bottlenecks can become a significant challenge, particularly with database queries…
medium.com
요즘 EntityFramework사용해서 작업 중입니다. EntityFramework는 쿼리 로그 옵션을 넣어서 프로그램을 동작하면 실행하는 모든 쿼리에 대한 로그를 볼 수 있습니다. 이는 편하지만 프로그램에서 사용하는 모든 쿼리를 봐야 하기 때문에 오래 걸리거나 문제가 있는 쿼리만 추출하기는 어려운 점이 있습니다.
그래서 느린 쿼리 관련 구글링 하다가 느린 쿼리만 찍는 코드를 찾아 공유합니다.
⌨ SlowQueryDetectionHelper 클래스 추가
- SlowQueryThreshlodInMillisecond를 5로 초기화했기 때문에 5 ms 이상 걸리는 쿼리들은 워닝으로 찍어냅니다.
- 🔥 DbCommandInterceptor 란?
: EF Core에서 실행되는 모든 SQL을 가로채서 수정하거나, 로깅할 수 있음.
public class SlowQueryDetectionHelper : DbCommandInterceptor
{
private const int SlowQueryThresholdInMilliSecond = 5;
public override ValueTask<DbDataReader> ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default)
{
if (eventData.Duration.TotalMilliseconds > SlowQueryThresholdInMilliSecond)
{
//여기서 각자한테 맞는 로그를 찍으면됨, 저는 NLog로 찍었습니다.
Log.Warn($"Slow Query Detected. {command.CommandText} TotalMilliSeconds: {eventData.Duration.TotalMilliseconds}");
}
return base.ReaderExecutedAsync(command, eventData, result,cancellationToken);
}
public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result)
{
if (eventData.Duration.TotalMilliseconds > SlowQueryThresholdInMilliSecond)
{
Log.Warn($"Slow Query Detected. {command.CommandText} TotalMilliSeconds: {eventData.Duration.TotalMilliseconds}");
}
return base.ReaderExecuted(command, eventData, result);
}
그리고 이 SlowQueryDataDetectionHelper를 최초에 초기화 시 option에 걸어서 사용하면 됩니다.
//Register DbContext
services.AddDbContext<YourDBContext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString(your-connection-string),
providerOption =>
{
providerOption.CommandTimeout(300);
});
//only on development environment
options.EnableSensitiveDataLogging();
options.AddInterceptors(new SlowQueryDetectionHelper());
});
return services;
}
그러면 프로그램 실행 시 5초 이상 걸리는 쿼리는 쿼리 내용과 수행시간이 찍힙니다.
이때 주의할 점은 이 쿼리 자체가 굉장히 중요한 정보일 수도 있으니 프로그램 실행환경에 맞춰 처리해야 합니다.