Производительность запросов в Django ORM
Я пытаюсь найти лучший django запрос для моего django приложения. Я использую стандартную sqlite DB в качестве бэкенда. Я использую timeit
для определения времени, затрачиваемого на запрос.
>>> import timeit
>>>
>>> setup_arg = 'from .models import AwsConsoleAccess'
>>> stmt1 = """AwsConsoleAccess.objects.filter(request_id='8548a2d5-4bb7-4fa9-add2-a41219dc8785')"""
>>> stmt2 = """AwsConsoleAccess.objects.filter(request_id='8548a2d5-4bb7-4fa9-add2-a41219dc8785').values('status')"""
>>>
>>>
>>> print(timeit.timeit(setup=setup_arg, stmt=stmt1, number=100) * 1000, 'ms')
7.873513997765258 ms
>>> print(timeit.timeit(setup=setup_arg, stmt=stmt2, number=100) * 1000, 'ms')
11.816384001576807 ms
SQL запрос выполнен
>>> print(AwsConsoleAccess.objects.filter(request_id='8548a2d5-4bb7-4fa9-add2-a41219dc8785').query)
SELECT "aws_console_awsconsoleaccess"."created",.....(all fields) FROM "aws_console_awsconsoleaccess" WHERE "aws_console_awsconsoleaccess"."request_id" = 8548a2d54bb74fa9add2a41219dc8785
>>> print(AwsConsoleAccess.objects.filter(request_id='8548a2d5-4bb7-4fa9-add2-a41219dc8785').values('status').query)
SELECT "aws_console_awsconsoleaccess"."status" FROM "aws_console_awsconsoleaccess" WHERE "aws_console_awsconsoleaccess"."request_id" = 8548a2d54bb74fa9add2a41219dc8785
Теоретически select field from table
должен работать быстрее, чем select * from table
, но мой результат не отражает этого.
- Правильно ли я провел тестирование?
- Есть ли другой способ проверить производительность между двумя запросами в DJango ORM?
Вы не учли тот факт, что QuerySets являются ленивыми, то есть при создании queryset не выполняется фактический запрос к базе данных. Запрос будет выполняться только тогда, когда результаты запроса действительно необходимы.
Поэтому, когда вы пишете Model.objects.filter(...)
, все, что это делает, - создает запрос. Вместо этого вы должны принудительно оценить набор запросов, например, преобразовав его в список. Это фактически выполнит запрос и даст вам более точные результаты:
list(Model.objects.filter(...))