[PYTHON] Experiment zum Timing des Django-Abfragesatzes

Auswertungszeitpunkt für Django-Abfragesätze http://djangoproject.jp/doc/ja/1.0/ref/models/querysets.html

Wir werden dies überprüfen, während wir tatsächlich SQL ausgeben.

** Vorbereitung **

Umgebung: Python 2.7.10 Django 1.9.7 MySQL 5.6.30

Daten: Erstellen Sie entsprechend eine einfache Buchverwaltungsklasse

mysql> select * from book_book;
+----+------+-------------+-----+----------------------------+----------------------------+
| id | name | description | tag | created_at                 | updated_at                 |
+----+------+-------------+-----+----------------------------+----------------------------+
|  1 | A    | A's book    | A   | 2016-06-22 01:50:25.895551 | 2016-06-22 01:50:25.895986 |
|  2 | B    | B's book    | B   | 2016-06-22 01:50:36.743094 | 2016-06-22 01:50:36.743139 |
|  3 | C    | C's book    | C   | 2016-06-22 01:50:46.279098 | 2016-06-22 01:50:46.279141 |
|  4 | D    | D's book    | D   | 2016-06-22 01:50:56.831194 | 2016-06-22 01:50:56.831237 |
|  5 | E    | E's book    | E   | 2016-06-22 01:51:06.663500 | 2016-06-22 01:51:06.663562 |
+----+------+-------------+-----+----------------------------+----------------------------+
5 rows in set (0.00 sec)

Anzeigen der Ausgabe von SQL:

settings.py


LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },

    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
        },
    }
}

** Trainieren **

Lassen Sie es uns zuerst bekommen.

>>> query = Book.objects.get(id=1)
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)

Als ich es mit get bekam, wurde SQL plötzlich ausgegeben. das ist,

>>> type(query)
<class 'book.models.Book'>

Weil es von einem Objekt abgerufen wird, nicht von einem Abfragesatz.

Wenn Sie dies in Filter ändern

>>> query = Book.objects.filter(id=1)
>>> type(query)
<class 'django.db.models.query.QuerySet'>

Es wird vom Abfragesatz abgerufen und zu diesem Zeitpunkt wird kein SQL ausgegeben. Befolgen Sie dieses Dokument, um die einzelnen Vorgänge auszuführen.

** Wiederholung **

>>> for book in query:
...   print book
... 
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
Book object

Scheibe

>>> query[:1]
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1 LIMIT 1; args=(1,)
[<Book: Book object>]

repr

>>> repr(query)
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1 LIMIT 21; args=(1,)
'[<Book: Book object>]'

len

>>> len(query)
(0.004) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
1

list

>>> list(query)
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]

Wie dokumentiert, hat jede Operation den Abfragesatz ausgewertet und SQL ausgegeben.

Zwischenspeicher

Ein Abfragesatz, der einmal ausgewertet wurde, wird zwischengespeichert, und es wird kein SQL ausgegeben, selbst wenn der Vorgang erneut ausgewertet wird.

>>> query = Book.objects.filter(id=1)
>>> list(query)
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]
>>> list(query)
[<Book: Book object>]
>>> list(query)
[<Book: Book object>]
>>> query[:1]
[<Book: Book object>]
>>> len(query)
1

Beachten Sie, dass hier der Abfragesatz zwischengespeichert wird, nicht SQL.

>>> #Die Bewertungsergebnisse für Abfragesätze werden zwischengespeichert
>>> for i in xrange(1, 5):
...   list(query)
... 
[<Book: Book object>]
[<Book: Book object>]
[<Book: Book object>]
[<Book: Book object>]
[<Book: Book object>]
>>> #SQL-Ergebnisse selbst werden nicht zwischengespeichert
>>> for i in xrange(1, 5):
...   list(Book.objects.filter(id=1))
... 
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]
(0.002) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]
(0.002) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)

Außerdem werden dem Abfragesatz hinzugefügte Bedingungen nicht zwischengespeichert. (Da das folgende Beispiel Book.objects.filter (id = 1) .order_by ('id') entspricht)

>>> query.order_by('id')
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1 ORDER BY `book_book`.`id` ASC LIMIT 21; args=(1,)
[<Book: Book object>]
>>> query.order_by('id')
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1 ORDER BY `book_book`.`id` ASC LIMIT 21; args=(1,)
[<Book: Book object>]

In diesem Fall wird es wie folgt zwischengespeichert.

>>> query2 = query.order_by('id')
>>> list(query2)
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1 ORDER BY `book_book`.`id` ASC; args=(1,)
[<Book: Book object>]
>>> list(query2)
[<Book: Book object>]

Da sich das ausgegebene SQL auch in der folgenden Reihenfolge ändert, scheint es, dass jedes einzeln ausgewertet wird.

>>> query = Book.objects.filter(id=1)
>>> query[:1]
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1 LIMIT 1; args=(1,)
[<Book: Book object>]
>>> list(query)
(0.001) SELECT `book_book`.`id`, `book_book`.`name`, `book_book`.`description`, `book_book`.`tag`, `book_book`.`created_at`, `book_book`.`updated_at` FROM `book_book` WHERE `book_book`.`id` = 1; args=(1,)
[<Book: Book object>]

Dies liegt daran, dass beim ersten Festlegen der Abfrage [: 1] der Abfrage von Book.objects.filter Limit 1 hinzugefügt wird (id = 1).

Recommended Posts

Experiment zum Timing des Django-Abfragesatzes
Django "Abfragesatz, Objekt hat keine Attribut'foo '" -Lösung