Why is Django ORM explain() function not giving expected output?

Question:

I’m trying to understand how the .explain() function works in Django ORM.

The official documentation here says this.

print(Blog.objects.filter(title='My Blog').explain())

gives below output.

Seq Scan on blog (cost=0.00..35.50 rows=10 width=12) Filter: (title

= ‘My Blog’::bpchar)

But if I try to print the same thing in my local Django shell, it is giving me different output like below.

print(OCUser.objects.all().explain())

gives

SIMPLE alyssa_ocuser None ALL None None None None 2853 100.0 None

which is not similar to the one in the official documentation.

I’m not sure what this SIMPLE, and all those None values are. Can someone please explain?

When I filter the query, I’m getting as below.

print(OCUser.objects.filter(chain_code=110).explain(format='text'))

1 SIMPLE alyssa_ocuser None ALL None None None None 2853 10.0 Using
where

Am I doing something wrong?

Python: 3.7.3
Django: 2.1.5
Mysql: Ver 14.14 Distrib 5.7.26
Asked By: Underoos

||

Answers:

The explain() literally translates to raw SQL EXPLAIN which is specific to the Database we are using.

In the official documentation, they’ve used Postgres where as I was using MySQL DB.

I got the output specific to MySQL which is same as EXPLAIN SELECT * FROM TABLE_NAME.

Answered By: Underoos

If you’re using MySQL, you can get the more readable result (i.e. including column headers for the EXPLAIN output) with some extra work: get the raw SQL for the query, then prefix that with EXPLAIN in a MySQL session.

E.g.

>>> from django.contrib.admin.models import LogEntry
>>> qs = LogEntry.objects.order_by("action_time")                                                                                                                   
>>> qs.query.sql_with_params()                                                                                                                                      
('SELECT `django_admin_log`.`id`, `django_admin_log`.`action_time`, `django_admin_log`.`user_id`, `django_admin_log`.`content_type_id`, `django_admin_log`.`object_id`, `django_admin_log`.`object_repr`, `django_admin_log`.`action_flag`, `django_admin_log`.`change_message` FROM `django_admin_log` ORDER BY `django_admin_log`.`action_time` ASC', ())

$ ./manage.py dbshell
mysql> EXPLAIN SELECT `django_admin_log`.`id`, `django_admin_log`.`action_time`, `django_admin_log`.`user_id`, `django_admin_log`.`content_type_id`, `django_admin_log`.`object_id`, `django_admin_log`.`object_repr`, `django_admin_log`.`action_flag`, `django_admin_log`.`change_message` FROM `django_admin_log` ORDER BY `django_admin_log`.`action_time` ASC;

+----+-------------+------------------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table            | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+------------------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | django_admin_log | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   19 |   100.00 | Using filesort |
+----+-------------+------------------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.01 sec)
Answered By: Paul Bissex