Django - необработанные SQL-запросы или Django QuerySet ORM - PullRequest
1 голос
/ 14 марта 2019

Я знаю, что Django Object Relational Mapper (ORM) помогает устранить разрыв между базой данных и нашим кодом. Выполнение необработанных запросов.

Но я хочу выяснить, что лучше - Raw SQL Queries или Django QuerySet ORM.

Итак, для этого я запросил User Table -

from django.contrib.auth.models import User

Затем я запросил Django ORM QuerySet -

orm_query = User.objects.all()
orm_query
<QuerySet [<User: superadmin>]>

После QuerySet I пользователь raw -

raw_query = User.objects.raw("select * from auth_user")
raw_query
<RawQuerySet: select * from auth_user>

А потом я попытался напечатать эти запросы, используя .query, и он вывел -

print(orm_query.query)
SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user`

print(raw_query.query)
select * from auth_user

И я нашел orm_query намного длиннее, чем raw_query. Я хочу знать, какой из них лучше всего raw или orm запрос. Который я должен использовать для лучшей производительности. В чем разница между ними.

Ответы [ 3 ]

3 голосов
/ 14 марта 2019

Запрос, сгенерированный ORM Джанго, явно выбирает каждый столбец, в то время как ваш необработанный запрос выбирает все столбцы с *. Результат должен быть одинаковым в обоих случаях, вы можете остаться без проблем с запросом ORM. Если вы хотите опустить определенные столбцы в результате, вы все равно можете использовать методы набора запросов only() и defer(), которые уменьшат полезную нагрузку, возвращаемую из базы данных, а также работа, необходимая для преобразования необработанных данных в объекты Python.

Скорее всего, вам нужно только обратиться к необработанным SQL-запросам для решения сценариев использования, на которые не способен ORM Django. В большинстве случаев наибольшее влияние на производительность будет вызвано неправильным доступом к связанным объектам (см. select_related() и prefetch_related() для получения дополнительной информации об этом) или неиспользованием индексы правильно. Также смотрите документацию Django по оптимизации доступа к базе данных .

2 голосов
/ 14 марта 2019

Неважно, какой длины текст SQL, если вы хотите сравнить производительность, вы должны использовать что-то вроде EXPLAIN ANALYZE (пример для postgres), прочитайте ответы для mysql

dev=> EXPLAIN ANALYZE SELECT
    auth_user.id,
    auth_user.password,
    auth_user.last_login,
    auth_user.is_superuser,
    auth_user.username,
    auth_user.first_name,
    auth_user.last_name,
    auth_user.email,
    auth_user.is_staff,
    auth_user.is_active,
    auth_user.date_joined 
FROM auth_user;
                                               QUERY PLAN                                               
--------------------------------------------------------------------------------------------------------
 Seq Scan on auth_user  (cost=0.00..10.50 rows=50 width=1527) (actual time=0.004..0.004 rows=0 loops=1)
 Planning time: 0.124 ms
 Execution time: 0.032 ms
(3 rows)

dev=> EXPLAIN ANALYZE select * from auth_user;
                                               QUERY PLAN                                               
--------------------------------------------------------------------------------------------------------
 Seq Scan on auth_user  (cost=0.00..10.50 rows=50 width=1527) (actual time=0.004..0.004 rows=0 loops=1)
 Planning time: 0.114 ms
 Execution time: 0.032 ms
(3 rows)

как видите, Execution time равно.

1 голос
/ 15 марта 2019

В целом, Django ORM довольно хорошо справляется с тем, что обычно требуется для запросов к базе данных.Это становится проще и особенно полезно для сложных запросов.Написание необработанных запросов для этих случаев может быть очень утомительным и занимать много времени.Вот почему время разработки может стать проблемой.В большинстве случаев ORM будет таким же быстрым, как необработанные запросы SQL.Поэтому ORM должен быть вашим выбором по умолчанию.

В тех немногих случаях, когда производительность может стать проблемой, следуйте рекомендациям в Ответ Бернхарда Валланта должен быть первым, что вы попробуете;select_related, prefecth_related, индексы базы данных и т. Д.

...