简体   繁体   English

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

[英]Django QuerySet vs. raw SQL performance considerations

I'm learning Django and its ORM data access methodology and there is something that I'm curious about.我正在学习 Django 及其 ORM 数据访问方法,并且有一些我很好奇的东西。 In one particular endpoint, I'm making a number of database calls (to Postgres) - below is an example of one:在一个特定的端点中,我进行了许多数据库调用(对 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]

As you can see, that's not a small query - I'm pulling in a lot of specific, related data and doing some string manipulation.正如您所看到的,这不是一个小查询 - 我正在提取大量特定的相关数据并进行一些字符串操作。 I'm relatively concerned with performance so I'm doing the best I can to make things more efficient by using select_related() and values() to only get exactly what I need.我比较关心性能,所以我尽我所能,通过使用select_related()values()来使事情更高效,只得到我需要的东西。

The question I have is, conceptually and in broad terms, at what point does it become faster to just write my queries using parameterized SQL instead of using the ORM (since the ORM has to first "translate" the above "mess")?我的问题是,从概念上和广义上讲,在什么时候只使用参数化 SQL 而不是使用 ORM 编写查询会变得更快(因为 ORM 必须首先“翻译”上面的“混乱”)? At what approximate level of query complexity should I switch over to raw SQL?我应该切换到原始 SQL 的查询复杂度大约是多少?

Any insight would be helpful.任何见解都会有所帮助。 Thanks!谢谢!

The question I have is, conceptually and in broad terms, at what point does it become faster to just write my queries using parameterized SQL instead of using the ORM (since the ORM has to first "translate" the above "mess")?我的问题是,从概念上和广义上讲,在什么时候只使用参数化 SQL 而不是使用 ORM 编写查询会变得更快(因为 ORM 必须首先“翻译”上面的“混乱”)?

If you are asking about performance, Never.如果您问的是性能,请从不。

The time taken to convert the ORM query into SQL will be very small compared to the time taken to actually execute that query.与实际执行该查询所花费的时间相比,将 ORM 查询转换为 SQL 所花费的时间将非常少。 Brain cells are irreplaceable, servers are cheap.脑细胞不可替代,服务器便宜。

If you are really do have performance issues the first place to look at is the your indexes in your models.如果您确实有性能问题,首先要查看的是模型中的索引。 Try printing out each of the queries generated by the ORM and run them in your psql console by prefixing EXPLAIN ANALYSE.尝试打印出 ORM 生成的每个查询,并通过添加 EXPLAIN ANALYSE 前缀在您的 psql 控制台中运行它们。

You can also use the django-debug-toolbar to automate this.您还可以使用 django-debug-toolbar 来自动执行此操作。 In fact django-debug toolbar is an essential tool to hunt down bottlenecks.事实上,django-debug 工具栏是寻找瓶颈的重要工具。 You will be surprised to note how often you have missed a simple select_related and how that causes hundreds of additional queries to be executed.您会惊讶地注意到您经常错过一个简单的select_related以及它如何导致执行数百个附加查询。

At what approximate level of query complexity should I switch over to raw SQL?我应该切换到原始 SQL 的查询复杂度大约是多少?

if you are asking about the ease of coding, it depends.如果您要问编码的难易程度,那就要看情况了。

If the query is very very hard to write using the ORM and it's unreadable, yes, then it's perfectly fine to use a raw query.如果使用 ORM 编写查询非常困难并且不可读,是的,那么使用原始查询完全没问题。 For example a query that has multiple aggregations, uses common table expressions, multiple joins etc can sometimes be hard to write as an ORM query, in that case if you are comfortable with raw sql writing it that way is fine.例如,具有多个聚合、使用公共表表达式、多个连接等的查询有时很难编写为 ORM 查询,在这种情况下,如果您对原始 sql 的编写方式感到满意,则很好。

Agreed with what @e4c5 said .同意@e4c5 所说的。

Additional translation layer for converting an ORM query to raw SQL query will effect performance.用于将 ORM 查询转换为原始 SQL 查询的附加转换层会影响性能。

However, this effect will depend on how much complex your query is?但是,这种效果将取决于您的查询有多复杂?

When you use ORM, you can control the load on DB by increasing the processing in the app.当您使用 ORM 时,您可以通过增加应用程序中的处理来控制 DB 上的负载。 In addition, this gives the opportunity to cache the result in the application itself.此外,这提供了在应用程序本身中缓存结果的机会。

At last, It totally depends on your schema , how complex your queries can be and how are you scaling your DB(Indices, replicas etc .)最后,这完全取决于您的架构、查询的复杂程度以及您如何扩展数据库(索引、副本等)。

For more read here更多信息请阅读这里

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

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