Django QuerySet 与原始 SQL 性能注意事项
Posted
技术标签:
【中文标题】Django QuerySet 与原始 SQL 性能注意事项【英文标题】:Django QuerySet vs. raw SQL performance considerations 【发布时间】:2017-11-03 21:56:09 【问题描述】:我正在学习 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?
任何见解都会有所帮助。谢谢!
【问题讨论】:
【参考方案1】:我的问题是,从概念上和广义上讲,在什么时候 使用参数化 SQL 编写查询是否会变得更快 而不是使用 ORM(因为 ORM 必须首先“翻译” 上面的“混乱”)?
如果你问的是性能,从不。
与实际执行该查询所需的时间相比,将 ORM 查询转换为 SQL 所需的时间将非常短。脑细胞无可替代,服务器便宜。
如果您确实有性能问题,首先要看的是模型中的索引。尝试打印出 ORM 生成的每个查询,并在您的 psql 控制台中通过添加 EXPLAIN ANALYSE 前缀来运行它们。
您也可以使用 django-debug-toolbar 来自动执行此操作。事实上 django-debug 工具栏是寻找瓶颈的重要工具。您会惊讶地发现您错过了一个简单的select_related
的频率以及这如何导致执行数百个额外的查询。
我应该切换到什么近似级别的查询复杂性 原始 SQL?
如果您询问编码的难易程度,这取决于。
如果查询非常难以使用 ORM 编写并且不可读,是的,那么使用原始查询非常好。例如,具有多个聚合、使用公用表表达式、多个连接等的查询有时可能难以编写为 ORM 查询,在这种情况下,如果您对原始 sql 感到满意,那么这样编写就可以了。
【讨论】:
【参考方案2】:同意@e4c5 所说的。
用于将 ORM 查询转换为原始 SQL 查询的附加转换层会影响性能。
但是,这种效果将取决于您的查询有多复杂?
当您使用 ORM 时,您可以通过增加应用程序中的处理来控制 DB 上的负载。此外,这提供了将结果缓存在应用程序本身中的机会。
最后,这完全取决于您的架构、查询的复杂程度以及您如何扩展数据库(索引、副本等)
更多信息请阅读here
【讨论】:
好文章。我想我可以打印出那个图表。 很高兴您喜欢它,如果您觉得有用,请点赞我的回答.. 谢谢 '用于将 ORM 查询转换为原始 SQL 查询的附加翻译层将影响性能' 如果您进行基准测试,您会发现完全相反。影响可以忽略不计。以上是关于Django QuerySet 与原始 SQL 性能注意事项的主要内容,如果未能解决你的问题,请参考以下文章
为啥通过 django QuerySet 进行查询比在 Django 中使用游标慢得多?
Django 1.9:为 QuerySet 创建复杂的自定义过滤器方法