Django - 原始SQL查询或Django QuerySet ORM

问题描述 投票:1回答:3

我知道Django对象关系映射器(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之后我用户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_queryraw_query长得多。我想知道哪一个是最好的raworm查询。我应该使用哪个以获得最佳性能。它们之间有什么区别。

django django-queryset django-orm django-mysql
3个回答
3
投票

Django的ORM生成的查询显式选择每一列,而原始查询选择*的所有列。在两种情况下结果应该相同,您可以保持ORM的查询没有任何问题。如果要从结果中省略某些列,您仍然可以使用查询集方法only()defer(),这将减少从数据库返回的有效负载以及将原始数据转换为python对象所需的工作。

很可能你只需要回到原始的sql查询来解决Django的ORM不具备的用例。在大多数情况下,最大的性能影响将是由于没有以正确的方式访问相关对象(请参阅select_related()prefetch_related()以获取更多信息)或未正确使用indexes。另请参阅Django关于database access optimization的文档。


2
投票

sql文本的长度无关紧要,如果要比较性能,你应该使用EXPLAIN ANALYZE(例如postgres),阅读答案for the 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
投票

一般来说,Django ORM非常擅长做你通常需要的数据库查询。它变得更容易,对复杂查询特别有用。为这些案例编写原始查询可能会变得非常繁琐且耗时。这就是开发时间可能成为问题的原因。在大多数情况下,ORM将与原始SQL查询一样快。所以ORM应该是你的默认选择。

在性能可能成为问题的少数情况下,遵循Bernhard Vallant's中的建议,答案应该是您尝试的第一件事; select_relatedprefecth_related,数据库索引等。

© www.soinside.com 2019 - 2024. All rights reserved.