Opened 13 months ago

Closed 5 months ago

#28574 closed New feature (fixed)

Add a QuerySet.explain() method

Reported by: Tom Forbes Owned by: Tom Forbes
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Tom Forbes Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When diagnosing slow queries it would be handy to have an explain method on the queryset. Currently if you have a queryset that is performing slowly and you want to use your databases EXPLAIN query to see why, you have to print the querysets query attribute, copy and paste the often verbose string into a database shell, add the appropriate explain syntax, fix any parameters that may be missing and execute it. This can be quite annoying.

Every database that is supported in core supports this, usually by adding EXPLAIN before the query. Simply returning whatever the database gives you (which is vastly different per vendor and even version) could be a good improvement.

Change History (13)

comment:1 Changed 13 months ago by Srinivas Reddy Thatiparthy

+1 for this .

comment:2 Changed 13 months ago by Tim Graham

Summary: Add a Queryset.explain() methodAdd a QuerySet.explain() method
Triage Stage: UnreviewedAccepted

It looks reasonable at first glance.

comment:3 Changed 13 months ago by Tom Forbes

Cc: Tom Forbes added
Owner: changed from nobody to Tom Forbes
Status: newassigned

comment:4 Changed 13 months ago by Tom Forbes

PR: https://github.com/django/django/pull/9053

On any select queryset you can do print(qs.explain()) and it will print the databases EXPLAIN output. There is a verbose and a format flag for backends that support it, e.g on Mysql/Postgres print(qs.explain(verbose=True, format='json'))

comment:5 Changed 12 months ago by Tom Forbes

Has patch: set

I've updated the patch to include documentation. This works well on all databases except MySQL, which returns a table structure rather than a human-readable strings like PostgreSQL. Without the pseudo-table headers it's not very useful, but it could be a lot more effort to add support for this (we would have to deal with lining up the column headers with the values, add support for returning the column names from the execute_sql function).

comment:6 Changed 10 months ago by Tim Martin

Patch needs improvement: set

comment:7 Changed 10 months ago by Tom Forbes

Patch needs improvement: unset

comment:8 Changed 7 months ago by Carlton Gibson

Triage Stage: AcceptedReady for checkin

Patch looks good.

comment:9 Changed 7 months ago by Carlton Gibson

Patch needs improvement: set
Triage Stage: Ready for checkinAccepted

The new tests fail on Oracle. Needs resolving. (Hopefully good to go then.)

comment:10 Changed 6 months ago by Tom Forbes

Patch needs improvement: unset

comment:11 Changed 6 months ago by Tom Forbes

I don't see how we can add support for Oracle, the way explaining query plans works is significantly different from any other implementation, including the fact that you cannot use SQL parameterized queries.

I've modified the patch to simply disable this feature on Oracle for now.

comment:12 Changed 6 months ago by Carlton Gibson

Triage Stage: AcceptedReady for checkin

This looks ready to go. Good work Tom!

comment:13 Changed 5 months ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In c1c163b4:

Fixed #28574 -- Added QuerySet.explain().

Note: See TracTickets for help on using tickets.
Back to Top