Django-原始SQL查询或Django QuerySet ORM

时间:2019-03-14 15:14:29

标签: django django-queryset django-orm django-mysql

我知道Django对象关系映射器(ORM)帮助弥合数据库与我们的代码之间的鸿沟。

但是我想找出哪个更好-原始SQL查询或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查询。我应该使用哪个以获得最佳性能。它们之间有什么区别。

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分: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相等。

答案 2 :(得分:1)

通常,Django ORM非常擅长完成数据库查询通常需要执行的操作。对于复杂的查询,它变得更容易并且特别有用。针对这些情况编写原始查询可能会变得非常乏味且耗时。这就是为什么开发时间可能成为问题。在大多数情况下,ORM将与原始SQL查询一样快。因此,ORM应该是您的默认选择。

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