Django QuerySet与原始SQL性能注意事项

时间:2017-06-02 13:07:42

标签: python django postgresql django-orm

我正在学习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?

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

2 个答案:

答案 0 :(得分:6)

  

我所拥有的问题在概念上和广义上都是在什么位置   使用参数化SQL编写查询会变得更快吗?   而不是使用ORM(因为ORM必须首先“翻译”   以上“乱七八糟”)?

如果您询问表现,请不要。

与实际执行该查询所花费的时间相比,将ORM查询转换为SQL所需的时间非常短。 Braincells是不可替代的,服务器很便宜。

如果你真的关心性能,首先要看的是你的索引。尝试打印出ORM生成的每个查询,并通过为EXPLAIN ANALYZE添加前缀在psql控制台中运行它们。

  

我应该切换到查询复杂度的大概水平   原始SQL?

如果您询问编码的简易性,则取决于此。

如果查询非常难以使用ORM编写并且它是不可读的,是的,那么使用原始查询就完全没问题了。

答案 1 :(得分:1)

同意@ e4c5的说法。

用于将ORM查询转换为原始SQL查询的其他转换层将影响性能。

但是,此效果取决于查询的复杂程度?

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

最后,它完全取决于您的架构,您的查询有多复杂以及如何扩展您的数据库(指数,副本等)

更多阅读here