繁体   English   中英

Django QuerySet 与原始 SQL 性能考虑因素

[英]Django QuerySet vs. raw SQL performance considerations

我正在学习 Django 及其 ORM 数据访问方法,并且有一些我很好奇的东西。 在一个特定的端点中,我进行了许多数据库调用(对 Postgres)——下面是一个例子:

projects = Project.objects\
            .filter(Q(first_appointment_scheduled=True) | (Q(active=True) & Q(phase=ProjectPhase.meet.value)))\
            .select_related('customer__first_name', 'customer__last_name',
                            'lead_designer__user__first_name', 'lead_designer__user__last_name')\
            .values('id')\
            .annotate(project=F('name'),
                      buyer=Concat(F('customer__first_name'), Value(' '), F('customer__last_name')),
                      designer=Concat(F('lead_designer__user__first_name'), Value(' '), F('lead_designer__user__last_name')),
                      created=F('created_at'),
                      meeting=F('first_appointment_date'))\
            .order_by('id')[:QUERY_SIZE]

正如您所看到的,这不是一个小查询 - 我正在提取大量特定的相关数据并进行一些字符串操作。 我比较关心性能,所以我尽我所能,通过使用select_related()values()来使事情更高效,只得到我需要的东西。

我的问题是,从概念上和广义上讲,在什么时候只使用参数化 SQL 而不是使用 ORM 编写查询会变得更快(因为 ORM 必须首先“翻译”上面的“混乱”)? 我应该切换到原始 SQL 的查询复杂度大约是多少?

任何见解都会有所帮助。 谢谢!

我的问题是,从概念上和广义上讲,在什么时候只使用参数化 SQL 而不是使用 ORM 编写查询会变得更快(因为 ORM 必须首先“翻译”上面的“混乱”)?

如果您问的是性能,请从不。

与实际执行该查询所花费的时间相比,将 ORM 查询转换为 SQL 所花费的时间将非常少。 脑细胞不可替代,服务器便宜。

如果您确实有性能问题,首先要查看的是模型中的索引。 尝试打印出 ORM 生成的每个查询,并通过添加 EXPLAIN ANALYSE 前缀在您的 psql 控制台中运行它们。

您还可以使用 django-debug-toolbar 来自动执行此操作。 事实上,django-debug 工具栏是寻找瓶颈的重要工具。 您会惊讶地注意到您经常错过一个简单的select_related以及它如何导致执行数百个附加查询。

我应该切换到原始 SQL 的查询复杂度大约是多少?

如果您要问编码的难易程度,那就要看情况了。

如果使用 ORM 编写查询非常困难并且不可读,是的,那么使用原始查询完全没问题。 例如,具有多个聚合、使用公共表表达式、多个连接等的查询有时很难编写为 ORM 查询,在这种情况下,如果您对原始 sql 的编写方式感到满意,则很好。

同意@e4c5 所说的。

用于将 ORM 查询转换为原始 SQL 查询的附加转换层会影响性能。

但是,这种效果将取决于您的查询有多复杂?

当您使用 ORM 时,您可以通过增加应用程序中的处理来控制 DB 上的负载。 此外,这提供了在应用程序本身中缓存结果的机会。

最后,这完全取决于您的架构、查询的复杂程度以及您如何扩展数据库(索引、副本等)。

更多信息请阅读这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM