Webprofiler's Database panel shows you what happened on one page load. Devel's dedicated query log goes further: it can log every query across a whole session or a whole set of requests, with full backtraces showing exactly which line of code issued each one — the tool you reach for once you've narrowed a problem down to "the database," from the earlier lessons in this section, and need to find the exact query and the exact calling code responsible.
What you'll learn in this lesson
- Enabling Drupal core's own query logging versus Devel's enhanced version
- Reading a query's full backtrace to find the responsible code
- Spotting slow individual queries versus high query counts — different problems
Core's built-in logging
// In settings.php — logs every query for the current request to the
// database log, viewable at /admin/reports/dblog.
$settings['extension_discovery_scan_tests'] = FALSE;
$config['system.logging']['error_level'] = 'verbose';
// Or, more directly, dump every query at the end of a request:
$queries = \Drupal::database()->getLogger()->get('default');
dump($queries); // Devel's dump() — pretty-printed, not raw var_dump().
Devel's enhanced query log
drush en devel -y
With Devel enabled and query logging turned on in its settings, every query gets recorded with a full PHP backtrace — not just the SQL text, but the exact function call chain that issued it. This is the piece core's own logging doesn't give you as conveniently: knowing a slow query ran is useful, knowing which line of your custom module triggered it is what actually lets you fix it.
loadMultiple(), a JOIN instead of a loop) — a code-structure fix. Reading the query log tells you which situation you're actually in before you start "optimizing" the wrong thing.A realistic debugging workflow
- Notice a page is slow (from Webprofiler's Time panel, or a user report).
- Check the Database panel — is it one slow query, or many fast duplicate ones?
- For one slow query: copy its exact SQL, run
EXPLAINon it directly against the database to see if it's missing an index. - For many duplicate queries: use the backtrace to find which loop in your code is issuing them one at a time, and batch it.
Quick check: the query log shows one single query taking 1.8 seconds, no duplicates. Is batching with
loadMultiple()the right fix here? If you said no — that's a single-query problem, likely needing an index or a rewritten condition, not a batching problem, which only helps when the same query pattern repeats many times — you've correctly distinguished the two failure modes this lesson covers.
Key takeaways
- Devel's query log adds full backtraces to core's own query logging — knowing which code issued a query, not just that it ran.
- A single slow query needs a query-level fix (indexing, rewriting); many fast duplicate queries need a code-structure fix (batching).
EXPLAINthe actual SQL directly against your database when a single query is genuinely slow — don't guess at indexes.- Always disable verbose query logging on production once you're done debugging — it adds real per-query logging overhead.
Coming up next
You've now got tools for diagnosing both module overhead and query problems. Next, we apply the same diagnostic discipline to caching specifically — confirming your cache configuration is actually working the way you think it is.