Django - 原始 SQL 查询或 Django QuerySet ORM
Django - Raw SQL Queries or Django QuerySet ORM
我知道 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_query
比 raw_query
长得多。
我想知道哪个是最好的 raw
或 orm
查询。我应该使用哪个以获得最佳性能。它们有什么区别呢
Django 的 ORM 生成的查询会明确选择每一列,而您的原始查询会选择带有 *
的所有列。两种情况下的结果应该是相同的,您可以毫无问题地使用 ORM 的查询。如果您想从结果中省略某些列,您仍然可以使用查询集方法 only()
and defer()
,这将减少从数据库返回的有效负载以及将原始数据转换为 python 所需的工作] 个对象。
很可能您只需要回退到原始 sql 查询来解决 Django 的 ORM 无法解决的用例。
在大多数情况下,最大的性能影响是由于没有以正确的方式访问相关对象造成的(参见 select_related()
and prefetch_related()
for more information on that) or not using indexes correctly. Also see Django's documentation on database access optimization.
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
相等。
一般来说,Django ORM 非常擅长执行数据库查询通常需要的操作。它变得更容易并且对复杂查询特别有用。为这些情况编写原始查询可能会变得非常乏味和耗时。这就是开发时间可能成为问题的原因。在大多数情况下,ORM 将与原始 SQL 查询一样快。所以ORM应该是你的默认选择。
在性能可能成为问题的少数情况下,遵循 答案中的建议应该是您首先要尝试的事情; select_related
、prefecth_related
、数据库索引等。
我知道 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_query
比 raw_query
长得多。
我想知道哪个是最好的 raw
或 orm
查询。我应该使用哪个以获得最佳性能。它们有什么区别呢
Django 的 ORM 生成的查询会明确选择每一列,而您的原始查询会选择带有 *
的所有列。两种情况下的结果应该是相同的,您可以毫无问题地使用 ORM 的查询。如果您想从结果中省略某些列,您仍然可以使用查询集方法 only()
and defer()
,这将减少从数据库返回的有效负载以及将原始数据转换为 python 所需的工作] 个对象。
很可能您只需要回退到原始 sql 查询来解决 Django 的 ORM 无法解决的用例。
在大多数情况下,最大的性能影响是由于没有以正确的方式访问相关对象造成的(参见 select_related()
and prefetch_related()
for more information on that) or not using indexes correctly. Also see Django's documentation on database access optimization.
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
相等。
一般来说,Django ORM 非常擅长执行数据库查询通常需要的操作。它变得更容易并且对复杂查询特别有用。为这些情况编写原始查询可能会变得非常乏味和耗时。这就是开发时间可能成为问题的原因。在大多数情况下,ORM 将与原始 SQL 查询一样快。所以ORM应该是你的默认选择。
在性能可能成为问题的少数情况下,遵循 select_related
、prefecth_related
、数据库索引等。