Interview question
Tag and inspect a slow EF Core query
Adds a stable query tag and inspects generated SQL without embedding user data or enabling unsafe global logging.
TL;DR
Adds a stable query tag and inspects generated SQL without embedding user data or enabling unsafe global logging.
TagWith, ToQueryString, stable identifiers, sensitive-data boundaries, projection, and evidence-driven tuning.
Practice the problem like a real interview: restate, reason, implement, and test.
An order-search endpoint is slow in production. Add a low-cardinality code-path tag to its EF Core query. Show how a developer can inspect the generated SQL locally before capturing an execution plan. Do not put search text, user ids, or tenant ids in the tag.
Move to the linked follow-up, next path step, prerequisite, or deeper variant.
Practice the next layer of the same subject.
Database telemetry shows the comment Orders.Search.v1, allowing the team to connect the SQL command to one endpoint without leaking request data.
ToQueryString for diagnosis, not query execution.I tag the query near its definition so the identifier survives refactoring and appears in generated SQL. Locally, ToQueryString reveals translation, selected columns, joins, ordering, and parameters. In production, dependency telemetry and database tools provide timing and plans; I do not enable detailed sensitive logging globally just to find one endpoint.
public static IQueryable<OrderSearchItem> BuildOrderSearch(
AppDbContext db,
OrderSearch request)
{
var query = db.Orders
.AsNoTracking()
.TagWith("Orders.Search.v1")
.Where(order => order.CreatedAtUtc >= request.FromUtc)
.Where(order => order.CreatedAtUtc < request.ToUtc);
if (request.Status is not null)
query = query.Where(order => order.Status == request.Status);
return query
.OrderByDescending(order => order.CreatedAtUtc)
.ThenByDescending(order => order.Id)
.Select(order => new OrderSearchItem(
order.Id,
order.Status,
order.CreatedAtUtc,
order.Total));
}
// Local investigation only; do not log this on every production request.
var generatedSql = BuildOrderSearch(db, request).Take(100).ToQueryString();
The tag changes observability, not query complexity. The final query remains parameterized and bounded by the caller. Useful investigation follows the tag from request telemetry to actual SQL duration, row estimates, logical reads, and execution plan.
ToQueryString as performance measurement.Spot a weak answer, missing edge case, or clearer explanation? Send it in.